PSET5 (Speller) Valgrind Error: Valgrind tests failed - cs50

I failed to pass the Valgrind tests and couldn't figure out what went wrong with my code. It seems like the issue is in the load() function as the Valgrind tests pointed out at the malloc() line. Could anyone help me take a look? Any guidance would be appreciated. Thank you!
Here is my code:
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// TODO: Choose number of buckets in hash table
const unsigned int N = 100;
// Hash table
node *table[N];
int count =0;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// TODO
int i = hash(word);
node *cursor = table[i];
if (table[i] == NULL)
{
return false;
}
else
{
while(cursor!= NULL)
{
if(strcasecmp(cursor->word, word) == 0)
{
return true;
}
else
{
cursor = cursor->next;
}
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// TODO: Improve this hash function
int bucket;
if(word[1] != 0)
{
bucket = (((toupper(word[0])-'A') * (toupper(word[1]- 'A')))% 10 + (toupper(word[0])-'A'));
}
else
{
bucket = (((toupper(word[0])-'A') * (toupper(word[0])-'A'))%10 + (toupper(word[0])-'A'));
}
return bucket;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// TODO 1
//open the dictionary
FILE *file = fopen(dictionary, "r");
if(file == NULL)
{
printf("Can't load the dictionary\n");
return false;
}
//read string from file one at a time
char word[LENGTH + 1];
for (int i=0; i < N; i++)
{
table[i] = NULL;
}
while(fscanf(file, "%s", word) != EOF)
{
node *n = malloc(sizeof(node));
//create a new node for each word
if(n == NULL)
{
unload();
return false;
}
strcpy(n->word, word);
n->next = NULL;
count++;
char *c = n->word;
int number = hash(c);
if (table[number] != NULL)
{
//point the new node to the first node existing in the table
n->next = table[number];
//point the header to the new node
table[number] = n;
}
else
{
//n->next = NULL;
table[number] = n;
}
}
fclose(file);
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// TODO
return count;
//return 0;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
for (int i = 0; i > N; i++)
{
node *cursor = table[i];
while(cursor != NULL)
{
node *tmp = cursor;
cursor = cursor->next;
free(tmp);
}
free(cursor);
}
// TODO
return true;
}
Here is what the Valgrind tests show:
Valgrind tests
c.99 is this line -> node *n = malloc(sizeof(node));

The problem is in unload. It doesn't free any nodes. Review this line carefully and critically, it contains the error.
for (int i = 0; i > N; i++)

Related

How do i print the char value from file c program?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 128
const char *FILE_GAME_DATA_PATH = "./game.txt";
struct game_tag
{
char gname[20];
struct game_tag *next;
} * head;
//struct game_tag g;
typedef struct game_tag GAME;
//file functions
void read_file();
//util functions.
int menu();
void print_game(GAME *game);
void release(GAME *data);
//core
void display_game();
void quite();
//link
int count_elements(GAME *elements);
int count();
int main(void)
{
int selected;
read_file();
while (1)
{
selected = menu();
switch (selected)
{
case 1:
display_game();
break;
default:
printf("cannot find your option!");
break;
}
}
}
void display_game()
{
read_file();
GAME *game = head;
if(game == NULL)
{
printf("\nNo Game!\n");
return;
}
print_game(game);
}
void print_game(GAME *game)
{
int records_count = 0;
printf("\n========== GAME ==========\n");
while(game != NULL)
{
printf("\n");
printf("Game Name: %s\n ", game->gname);
game = game->next;
records_count++;
}
printf("\nRecords: %d has been loaded successfully!\n", records_count);
release(game);
}
int menu()
{
printf("\n(1) Display Game details\n");
int choosen;
printf("\nEnter your option: ");
scanf("%d", &choosen);
return choosen;
}
void add_game(char game_name[20])
{
GAME *temp, *iterator;
temp = (struct game_tag *)malloc(sizeof(struct game_tag));
GAME info;
memcpy(info.gname, game_name, 20);
//temp = head;
iterator = head;
if (head == NULL)
{
head = temp;
head->next = NULL;
}
else
{
while (iterator->next != NULL)
{
iterator = iterator->next;
}
temp->next = NULL;
iterator->next = temp;
}
}
void read_file()
{
if(head != NULL)
{
GAME *temp;
while(head != NULL)
{
temp = head;
head = head->next;
free(temp);
}
}
FILE *file;
file = fopen(FILE_GAME_DATA_PATH, "r");
if(file == NULL)
{
printf("Cannot read file: %s", FILE_GAME_DATA_PATH);
exit(EXIT_FAILURE);
}
char game_name[20];
int i;
while(!feof(file))
{
char no[BUFFER_SIZE];
fgets(game_name, sizeof(game_name), file);
i=0;
while(game_name[i] != '\0')
{
i++;
}
game_name[i] = '\0';
add_game(game_name);
}
fclose(file);
}
void quite()
{
printf("\nGoodbye!");
exit(EXIT_SUCCESS);
}
void release(GAME *data)
{
if (data == NULL)
{
return;
}
// free the nodes
// because it can be use in memory
// we need to clear it first
// before we re-initailize the new data
GAME *temp;
while (data != NULL)
{
temp = data;
data = data->next;
free(temp);
}
}
(1) At this point, I have created the main function
(2) I'm trying to print the value from txt file which is char value that less than 20byte
(3) My error is it read the file properly, but it returns the garbage value
!Error I'm concern that my read_file function doesn't read txt proper or there an error in my condition statement

CS50 speller pset 5 (accessed 1 byte that does not belong to me but can't find the byte)

After running my code through help50 Valgrind, I got the following error message:
==6830== Invalid read of size 1
==6830== at 0x4C33614: strcasecmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6830== by 0x401176: check (dictionary.c:52)
==6830== by 0x400CD9: main (speller.c:112)
Looks like you're trying to access 1 byte of memory that isn't yours? Did you try to index into an array beyond its bounds? Take a closer look at line 52 of dictionary.c.
I think it has something to do with my check function but line 52 is just an if statement and I can't figure out where I'm trying to access that 1 byte from.**
My code is below:
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <strings.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Number of buckets in hash table
const unsigned int N = 1000;
//Number of words
unsigned int noWords = 0;
//Variable to check if dictionary loaded
bool isLoaded = false;
// Hash table
node *table[N];
// Returns true if word is in dictionary else false
bool check(const char *word)
{
//Changing letters to lower case because case insensitive
//Copy created because word argument is a constant. copy can be edited
int n = strlen(word) + 1;
char copy[LENGTH + 1];
for (int i = 0; i < n; i++)
{
copy[i] = tolower(word[i]);
}
// Add null terminator to end string
copy[n] = '\0';
//Hash the word to convert it to index and check if it's in any of the linked lists
int index = hash(copy);
if (table[index] != NULL) //Check if word is in linked list
{
for (node *cursor = table[index]; cursor != NULL; cursor = cursor -> next)
{
if (strcasecmp(cursor -> word, copy) == 0)
{
return true;
}
}
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
//Taken from http://www.cse.yorku.ca/~oz/hash.html (by djb2)
unsigned long h = 5381;
int c;
while ((c = *word++))
{
c = tolower(c);
h = (((h << 5) + h) + c) % N; /* hash * 33 + c*/
}
return h;
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
char word[LENGTH + 1];
//Open dictionary
FILE *f = fopen(dictionary, "r");
//Check if file can be opened
if (f == NULL)
{
printf("%s\n", "File cannot be opened!");
return false;
}
//Read strings from file
while (fscanf(f, "%s", word) != EOF)
{
noWords++;
node *newNodePointer = malloc(sizeof(node));
if (newNodePointer == NULL)
{
unload();
printf("Out of memory");
return false;
}
int index = hash(word);//hashtable is an array of linked list. index helps insert node into hashtable
strcpy(newNodePointer -> word, word);//Copies word from infile into new node's word field
if (table[index] == NULL)//Check if same word already exists in the bucket
{
newNodePointer -> next = NULL;
table[index] = newNodePointer;
}
else
{
newNodePointer -> next = table[index];
table[index] = newNodePointer;
}
free(newNodePointer);
}
fclose(f);
isLoaded = true;
return true;
}
// Returns number of words in dictionary if loaded else 0 if not yet loaded
unsigned int size(void)
{
if (isLoaded)
{
return noWords;
}
return 0;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
//Check if there's even a loaded dictionary
if (!isLoaded)
{
return false;
}
//Iterate through hashtable
for (int i = 0; i < N; i++)
{
if (table[i] != NULL)
{
node *cursor = table[i];
while (cursor != NULL)
{
node *tmp = table[i]; //tmp pointer continues pointing at table[i] while cursor points at next item in hashtable
cursor = cursor -> next;
free(tmp);
}
}
}
return true;
}
The problem is from here in load: free(newNodePointer);. It just released the memory where the word and the next pointer are stored!

CS50 pset5 SPELLER - most basic words & substrings issues

I have been stuck in pset5 for a while now. No matter from which angle I look to my code I cannot fin out what is wrong with it. I set my number of buckets randomly to 1000. Can someone find out the problem?
Below is the reply I get from check50
:) dictionary.c, dictionary.h, and Makefile exist
:) speller compiles
:( handles most basic words properly
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:) handles min length (1-char) words
:) handles max length (45-char) words
:) handles words with apostrophes properly
:) spell-checking is case-insensitive
:( handles substrings properly
expected "MISSPELLED WOR...", not "MISSPELLED WOR..."
:| program is free of memory errors
can't check until a frown turns upside down
these is what I've done:
const unsigned int N = 1000;
// Returns true if word is in dictionary else false
bool check(const char *word)
{
//convert *word to lowercase so that the hash function is case-insensitive
int length = strlen(word);
char copy[length + 1];
for (int i = 0; i < length; i++)
{
copy[i] = tolower(word[i]);
}
// create a variable to return hashed value of word
int index_check = hash(copy);
//create cursor to traverse the linked list
node *cursor = table[index_check];
//check if word is in the linked list
while (cursor != NULL)
{
if (strcasecmp(word, cursor->word) == 0)
{
return true;
}
cursor = cursor->next;
}
//return false if cursor->next = NULL has been reached
return false;
}
// Hashes word into a number
unsigned int hash(const char *word)
{
// Source of hash function: stackoverflow.com/questions/14409466/simple-hash-functions
unsigned int count;
unsigned int hashValue = 0;
for(count = 0; word[count] != '\0'; count++)
{
hashValue = word[count] + (hashValue << 6) + (hashValue << 16) - hashValue;
}
return (hashValue % N);
}
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
// open dictionary file
FILE *f = fopen(dictionary, "r");
if (f == NULL)
{
printf("Dictionary could not be opened\n");
return false;
}
//initialize string as a buffer, to be used in next function, fscanf
char buffer[LENGTH + 1];
//loop to check whether end of file has been reached
while (fscanf(f, "%s", buffer) != EOF)
{
//read words from file into buffer
fscanf(f, "%s", buffer);
//allocate memory for a node and check if NULL
node *n = malloc(sizeof(node));
if (n == NULL)
{
printf("Could not allocate memmory (malloc *n)\n");
return false;
}
//copy "buffer" into the node created
strcpy(n->word, buffer);
//call hash function
int index = hash(buffer);
//check if it's the first word being inserted into that bucket
if (table[index] == NULL)
{
table[index] = n;
}
else
{
n->next = table[index];
table[index] = n;
}
size_dictionary++;
}
fclose(f);
return true;
}
// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
node *cursor;
node *tmp;
// run thru all buckets
for(int i = 0; i < N; i++)
{
//check if bucket isn't NULL
if(table[i] != NULL)
{
cursor = table[i];
tmp = cursor;
while (tmp != NULL)
{
cursor = cursor->next;
free(tmp);
tmp = cursor;
}
}
}
return true;
}
The clue is in WORDS IN DICTIONARY. Only half the words in dictionary are loaded. That is because of the back-to-back fscanf in load.
tiagoK, I think I'm having the same issue here and been stuck with this exercice for days. What did you mean by " the loop should have been done with lenght + 1", where did you declare this string ? I've tried it on the strcasecmp field and the hash one but it doesn't change anything. Do you remember ?
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "dictionary.h"
// Represents a node in a hash table
typedef struct node
{
char word[LENGTH + 1];
struct node *next;
}
node;
// Choose number of buckets in hash table
const unsigned int N = 17576;
// Hash table
node *table[N];
// Initialize new variables used in the program
unsigned int numberofwords;
unsigned int hashvalue;
// Returns true if word is in dictionary, else false
bool check(const char *word)
{
// Hash the word to determine its hash value
hashvalue = hash(word);
// Set cursor to the head of the linked list of the word
node* cursor = table[hashvalue];
// Traverse into the linked list comparing the word to find a correspondance while the cursor isn't pointing to null
while (cursor != NULL)
{
if (strcasecmp(cursor->word, word) == 0)
{
return true;
}
cursor = cursor->next;
}
return false;
}
// Hashes word to a number
unsigned int hash(const char *word)
{
// Inittialize a variable to keep track of the total of ASCII values
unsigned int sum = 0;
// Loop in all the letters in the word
for (int i = 0 ; i < strlen(word) ; i++)
{
// Ignore digits
if (isdigit(word[i]))
{
continue;
}
else if (isalpha(word[i]) || word[i] == ('\''))
{
// Check the first three character in the word while setting them lower letters in order to get they ASCII value
sum += tolower(word[0] - 'a');
sum += tolower(word[1] - 'a');
sum += tolower(word[2] - 'a');
}
}
// Divide the total of the three letters by the number of buckets
hashvalue = sum % N;
return hashvalue;
}
// Loads dictionary into memory, returning true if successful, else false
bool load(const char *dictionary)
{
// Open the file
FILE* file = fopen(dictionary, "r");
char word[LENGTH + 1];
{
if (file != NULL)
{
// While dictionary doesn't return EOF, read strings from the file, one at the time
while (fscanf(file, "%s", word) != EOF)
{
// Create a new node for the word and copy it in the node
node *n = malloc(sizeof(node));
if (n == NULL)
{
return 1;
}
strcpy (n->word, "%s");
// Hash word to obtain a hash value
hashvalue = hash(word);
// Insert word into hash table depending if it's the first word or not
if (table[hashvalue] != NULL)
{
n->next = table[hashvalue];
}
else
{
n->next = NULL;
}
table[hashvalue] = n;
// Add one to the counter
numberofwords++;
}
fclose(file);
}
else
{
fclose(file);
perror("Loading error");
return 1;
}
}
// Return true
return true;
}
// Returns number of words in dictionary if loaded, else 0 if not yet loaded
unsigned int size(void)
{
// Return the number of words we're keeping track of while loading the dictionary
return numberofwords;
}
// Unloads dictionary from memory, returning true if successful, else false
bool unload(void)
{
// Check all the head of the hash table
for(int i = 0; i < N; i++)
{
// Create a temporary node to not lose the rest of the linked list
node* cursor = table[i];
// Set the cursor to the next node while the temporary value remains at the inital location, then free it before to move to cursor
while(cursor != NULL)
{
node* tmp = cursor;
cursor = cursor->next;
free(tmp);
}
}
return true;
}

Linked list sorted insert first time try

I am trying to code a c++ program for sorted insert of a linked list. I have given the code below. The problem is when doing my second insert i.e., insert(&head, 45); the head value is becoming 0 inside insert() function. I could not insert my second element and getting errors. Can anyone please help.
#include "stdafx.h"
#include <conio.h>
#include <iostream>
using namespace std;
struct node
{
int data;
node *next;
};
void insert (node** head, int key)
{
if(*head == NULL)
{
cout <<"List is empty, Inserting at first posistion"<<endl;
*head = new node;
(*head)->data = key;
(*head)->data = NULL;
}
else
{
struct node* temp;
temp = new node;
temp = *head;
if(key < temp->data)
{
cout<<"Key is smaller than first element. Inserting at first and moving"<<endl;
struct node* ctemp = new node;
ctemp->data = key;
ctemp->next = (*head);
//delete(ctemp);
return;
}
while(temp->next != NULL)
{
if(key > temp->data)
{
temp = temp->next;
}else
{
cout<<"Inserting the data at middle"<<temp->data<<" here"<<endl;
struct node* temp1 = new node;
temp1->data = key;
temp1->next = temp->next;
temp->next = temp1;
delete(temp1);
return;
}
}
if(key > temp->data)
{
cout<<"Inserting at last"<<endl;
struct node* last = new node;
last->data = key;
last->next = NULL;
temp->next = last;
delete(last);
return;
}
}
}
void print(struct node *head)
{
struct node* temp = head;
cout<<"Element in the list"<<endl;
while(temp != NULL)
{
cout<<temp->data<<"->";
temp = temp->next;
}
delete(temp);
}
int main()
{
struct node* head = NULL;
insert(&head, 21);
insert(&head, 45);
insert(&head, 5);
print(head);
getch();
delete(head);
return 0;
}
Change (*head)->data = NULL; to (*head)->next = NULL; if the list is empty.

shell execute with c++

I am working on an application that will trigger a UAC prompt in whatever program is opened by ShellExecute.
I can't figure out how to hard-code a path for the ShellExecute to run. As of now this program uses whatever path is in arg[0]. How can I build a string to put in the place of arg[0] on the line sinfo.lpFile = arg[0];?
I am very new so if you can't see why making a string to put in that line will solve my problem then you are most likely right.
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <shellapi.h>
#include <process.h>
#include "uac-example.h"
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst,LPSTR cmdLine, int nCmdShow){
LPWSTR *arg;
int argc = 0;
HRESULT ret = SUCCESS;
WCHAR imagePath[MAXPATHLEN];
WCHAR workingDir[MAXPATHLEN];
WCHAR uacDir[MAXPATHLEN];
WCHAR uacRunningLockFilePath[MAXPATHLEN];
HANDLE uacRunningLockFileHandle = INVALID_HANDLE_VALUE;
WCHAR elevatedLockFilePath[MAXPATHLEN];
HANDLE elevatedLockFileHandle = INVALID_HANDLE_VALUE;
arg = CommandLineToArgvW(GetCommandLineW(),&argc);
//if(arg == NULL || argc < 2) {
// ERRORBOX("Missing required program arguments.\n\nUsage:\nuac-example.exe <working directory>");
// return FAILURE;
//}
GetModuleFileName(NULL, imagePath, MAXPATHLEN);
arg[0] = imagePath;
wcscpy_s((wchar_t *)uacDir, MAXPATHLEN, arg[1]);
_snwprintf_s(uacRunningLockFilePath, MAXPATHLEN, MAXPATHLEN,
_T("%s/") _T(RUNNING_LOCK_FILE), uacDir);
wcscpy_s(workingDir, MAXPATHLEN, imagePath);
WCHAR *slash = wcsrchr(workingDir, '\\');
wcscpy_s(slash, MAXPATHLEN, _T(""));
_snwprintf_s(elevatedLockFilePath, MAXPATHLEN, MAXPATHLEN,_T("%s/") _T(ELEVATE_LOCK_FILE), workingDir);
uacRunningLockFileHandle = CreateFileW(uacRunningLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE _ON_CLOSE,NULL);
if (uacRunningLockFileHandle == INVALID_HANDLE_VALUE) {
if (_waccess(elevatedLockFilePath, F_OK) == 0 &&
_wremove(elevatedLockFilePath) != 0) {
return FAILURE;
}
elevatedLockFileHandle = CreateFileW(elevatedLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE _ON_CLOSE,NULL);
if(elevatedLockFileHandle == INVALID_HANDLE_VALUE){
ERRORBOX("Unable to acquire the necessary permissions to run demo app.");
return FAILURE;
}
LPWSTR spawnCmdLine = BuildCommandLine(argc - 1, arg + 1);
if(!spawnCmdLine){
CloseHandle(elevatedLockFileHandle);
ERRORBOX("An error occured while respawning self.");
return FAILURE;
}
SHELLEXECUTEINFO sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
sinfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS;
sinfo.hwnd = NULL;
sinfo.lpFile = arg[0];
sinfo.lpParameters = spawnCmdLine;
sinfo.lpVerb = L"runas"; // <<-- this is what makes a UAC prompt show up
sinfo.nShow = SW_SHOWMAXIMIZED;
BOOL result = ShellExecuteEx(&sinfo);
LocalFree(spawnCmdLine);
if(result){
WaitForSingleObject(sinfo.hProcess, INFINITE);
CloseHandle(sinfo.hProcess);
return SUCCESS;
}else{
return FAILURE;
}
}
EXIT_IF_ELEVATED(elevatedLockFilePath,uacRunningLo ckFileHandle,SUCCESS);
LocalFree(arg);
return SUCCESS;
}
// ----------------------------------------------------------------------
// The following code was taken directly from the Mozilla Firefox Updater
// source tree, and slightly modified to support "Wide" strings in
// Visual C++.
// ----------------------------------------------------------------------
LPWSTR
BuildCommandLine(int argc, LPWSTR *argv){
int i;
int len = 0;
// The + 1 of the last argument handles the
// allocation for null termination
for (i = 0; i < argc; ++i) {
len += ArgStrLen(argv[i]) + 1;
}
// Protect against callers that pass 0 arguments
if (len == 0) {
len = 1;
}
LPWSTR s = (LPWSTR)malloc(len * sizeof(LPWSTR));
if (!s) {
return NULL;
}
LPWSTR c = s;
for (i = 0; i < argc; ++i) {
c = ArgToString(c, argv[i]);
if (i + 1 != argc) {
*c = ' ';
++c;
}
}
*c = '\0';
return s;
}
int
ArgStrLen(LPWSTR s) {
int backslashes = 0;
int i = wcslen(s);
BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
if (addDoubleQuotes) {
i += 2; // initial and final duoblequote
}
if (hasDoubleQuote) {
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
i += backslashes + 1;
}
backslashes = 0;
}
++s;
}
}
return i;
}
LPWSTR
ArgToString(LPWSTR d, LPWSTR s) {
int backslashes = 0;
BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
if (addDoubleQuotes) {
*d = '"'; // initial doublequote
++d;
}
if (hasDoubleQuote) {
int i;
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes\
// preceding the doublequote
for (i = 0; i <= backslashes; ++i) {
*d = '\\';
++d;
}
}
backslashes = 0;
}
*d = *s;
++d; ++s;
}
} else {
wcscpy(d, s);
d += wcslen(s);
}
if (addDoubleQuotes) {
*d = '"'; // final doublequote
++d;
}
return d;
}
Simply as:
char path[] = "C:\\program.exe";
sinfo.lpFile = path;

Resources