尝试将换行符添加到 char 数组的末尾时,strcat 不起作用
strcat does not work when trying to add a newline character to the end of a char array
我有一个双指针字符数组,用于存储字符串行。我的功能是解析从文件中读取的一行,然后将每个解析的项目存储到一个名为 "intermediate.txt" 的不同文件中。我希望每个解析的项目都在其字符串的末尾添加一个新行,因此在中间文件中,每个解析的项目都在其自己的行上。
我正在尝试使用 strcat,它似乎对每一行都能正常工作,但 brokenUpLine[4] 除外。 (我故意跳过第三个索引处的元素)。 brokenUpLine[4] 此时正在存储 "error codes"。我想在字符串的末尾添加一个换行符,但它一直在崩溃。如果我删除这行代码,它工作正常但在我添加它时崩溃。有人能帮我解释一下为什么会崩溃吗?这是代码:
void assemblePass1(FILE * sourceF)
{
int i;
char line[260];
char ** brokenUpLine;
op * opCodes = createOPtable();
if (opCodes == NULL)
{
printf("Error allocating memory!\n\n");
return;
}
char * fn = "intermediate.txt";
FILE * imfp = checkForFileErrors(fn);
if (imfp != NULL)
imfp = fopen(fn, "w+");
else
return;
while (fgets(line, 260, sourceF) != NULL) //read line from source file
{
//write current source line to intermediate file
fprintf(imfp, line);
//breaks up line into values, write each value on new line in intermediate.txt
brokenUpLine = breakUpLine(line); //remember to free brokenUpLine
strcat(brokenUpLine[0], "\n");
strcat(brokenUpLine[1], "\n");
strcat(brokenUpLine[2], "\n");
strcat(brokenUpLine[4], "\n"); //*crashes at this line*
fprintf(imfp, brokenUpLine[0]); //write label to file
fprintf(imfp, brokenUpLine[1]); //write opcode to file
fprintf(imfp, brokenUpLine[2]); //write operand to file
fprintf(imfp, brokenUpLine[3]); //write comments to file
fprintf(imfp, brokenUpLine[4]); //write error code to file
for (i = 0; i < 5; i++)
{
brokenUpLine[i] = NULL;
free(brokenUpLine[i]);
}
free(brokenUpLine);
break; //for testing
}
free(opCodes);
fclose(imfp);
printf("Opening file was a success!\n\n");
}
这里是 breakUpLine():
char ** breakUpLine(char * line)
{
int row = 5, cols = 150, i;
char * string = NULL;
char ** arr = (char**)malloc(row * sizeof(char*)); //allocate 5 rows of memory (label(0), opcode(1), operand(2), comment(3), error code(4))
for (i = 0; i < row; i++)
arr[i] = (char*)malloc(cols * sizeof(char)); //allocates 150 columns to store a string per row
char * token = NULL;
i = 0;
if (line[0] == ' ') //if there is no label, assign to the label row an empty space
{
arr[0] = " "; //store a space in label column to indicate it has no label
i = 1;
}
token = strtok(line, " \t"); //get first token; break up by spaces or tabs
if (token[0] == '.') //if a period is found at beginning of line, then the line is an entire comment
{
token = strtok(NULL, "\n"); //store entire comment sentence including the spaces, so update token delimeter to a newline character
arr[0] = ".";
arr[1] = "\n";
arr[2] = "\n";
arr[3] = token; //store comment in comment row
arr[4] = NULL; //error code will be 0 or NULL if no error was detected
return arr; //remember to free arr in assemblePass1()
}
arr[i++] = token; //store token in appropriate row
while (token != NULL && i != 3)
{
token = strtok(NULL, " \t");
arr[i++] = token;
//totest:printf("%s\n", arr[i-2]);
}
//totest:printf("%s\n", arr[i - 1]);
token = strtok(NULL, "\t"); //process comments
arr[i] = token; //store comment in comment column
arr[4] = "Error code"; //error code will go here
return arr;
}
你因为这一行而崩溃:
arr[4] = NULL; //error code will be 0 or NULL if no error was detected
因为您随后尝试 strcat
指向此 NULL
指针:
strcat(brokenUpLine[4], "\n"); //*crashes at this line*
也许这意味着:
strcat(brokenUpLine[3], "\n");
???
你这里也有问题:
arr[0] = ".";
arr[1] = "\n";
arr[2] = "\n";
这些应该是:
strcpy(arr[0], ".");
strcpy(arr[1], "\n");
strcpy(arr[2], "\n");
否则,当您尝试 strcat
这些字符串时,您会遇到 (a) 未定义的行为,(b) 三个内存泄漏,以及 (c) 如果稍后尝试 free()
甚至更多未定义的行为这些字符串。
我有一个双指针字符数组,用于存储字符串行。我的功能是解析从文件中读取的一行,然后将每个解析的项目存储到一个名为 "intermediate.txt" 的不同文件中。我希望每个解析的项目都在其字符串的末尾添加一个新行,因此在中间文件中,每个解析的项目都在其自己的行上。
我正在尝试使用 strcat,它似乎对每一行都能正常工作,但 brokenUpLine[4] 除外。 (我故意跳过第三个索引处的元素)。 brokenUpLine[4] 此时正在存储 "error codes"。我想在字符串的末尾添加一个换行符,但它一直在崩溃。如果我删除这行代码,它工作正常但在我添加它时崩溃。有人能帮我解释一下为什么会崩溃吗?这是代码:
void assemblePass1(FILE * sourceF)
{
int i;
char line[260];
char ** brokenUpLine;
op * opCodes = createOPtable();
if (opCodes == NULL)
{
printf("Error allocating memory!\n\n");
return;
}
char * fn = "intermediate.txt";
FILE * imfp = checkForFileErrors(fn);
if (imfp != NULL)
imfp = fopen(fn, "w+");
else
return;
while (fgets(line, 260, sourceF) != NULL) //read line from source file
{
//write current source line to intermediate file
fprintf(imfp, line);
//breaks up line into values, write each value on new line in intermediate.txt
brokenUpLine = breakUpLine(line); //remember to free brokenUpLine
strcat(brokenUpLine[0], "\n");
strcat(brokenUpLine[1], "\n");
strcat(brokenUpLine[2], "\n");
strcat(brokenUpLine[4], "\n"); //*crashes at this line*
fprintf(imfp, brokenUpLine[0]); //write label to file
fprintf(imfp, brokenUpLine[1]); //write opcode to file
fprintf(imfp, brokenUpLine[2]); //write operand to file
fprintf(imfp, brokenUpLine[3]); //write comments to file
fprintf(imfp, brokenUpLine[4]); //write error code to file
for (i = 0; i < 5; i++)
{
brokenUpLine[i] = NULL;
free(brokenUpLine[i]);
}
free(brokenUpLine);
break; //for testing
}
free(opCodes);
fclose(imfp);
printf("Opening file was a success!\n\n");
}
这里是 breakUpLine():
char ** breakUpLine(char * line)
{
int row = 5, cols = 150, i;
char * string = NULL;
char ** arr = (char**)malloc(row * sizeof(char*)); //allocate 5 rows of memory (label(0), opcode(1), operand(2), comment(3), error code(4))
for (i = 0; i < row; i++)
arr[i] = (char*)malloc(cols * sizeof(char)); //allocates 150 columns to store a string per row
char * token = NULL;
i = 0;
if (line[0] == ' ') //if there is no label, assign to the label row an empty space
{
arr[0] = " "; //store a space in label column to indicate it has no label
i = 1;
}
token = strtok(line, " \t"); //get first token; break up by spaces or tabs
if (token[0] == '.') //if a period is found at beginning of line, then the line is an entire comment
{
token = strtok(NULL, "\n"); //store entire comment sentence including the spaces, so update token delimeter to a newline character
arr[0] = ".";
arr[1] = "\n";
arr[2] = "\n";
arr[3] = token; //store comment in comment row
arr[4] = NULL; //error code will be 0 or NULL if no error was detected
return arr; //remember to free arr in assemblePass1()
}
arr[i++] = token; //store token in appropriate row
while (token != NULL && i != 3)
{
token = strtok(NULL, " \t");
arr[i++] = token;
//totest:printf("%s\n", arr[i-2]);
}
//totest:printf("%s\n", arr[i - 1]);
token = strtok(NULL, "\t"); //process comments
arr[i] = token; //store comment in comment column
arr[4] = "Error code"; //error code will go here
return arr;
}
你因为这一行而崩溃:
arr[4] = NULL; //error code will be 0 or NULL if no error was detected
因为您随后尝试 strcat
指向此 NULL
指针:
strcat(brokenUpLine[4], "\n"); //*crashes at this line*
也许这意味着:
strcat(brokenUpLine[3], "\n");
???
你这里也有问题:
arr[0] = ".";
arr[1] = "\n";
arr[2] = "\n";
这些应该是:
strcpy(arr[0], ".");
strcpy(arr[1], "\n");
strcpy(arr[2], "\n");
否则,当您尝试 strcat
这些字符串时,您会遇到 (a) 未定义的行为,(b) 三个内存泄漏,以及 (c) 如果稍后尝试 free()
甚至更多未定义的行为这些字符串。