问题是当我将代码分成不同的函数时会发生这种情况
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//------Options -- change only true / false to trigger the function
bool hard_trace = false;
bool trace = true;
/*-------------------*/
//---------Defines----------
#define MAXSIZE 100 // maximum size of the characters in txt file to be buffed
/*----------------------*/
//---------Structs-----------
struct Matrix
{
char *A[10];
int depth;
};
/*--------------------------*/
//-----Variable----------
//-- global
char *B[3];
//- struct
struct Matrix matrixs ; // create new global struct
//-
//--
/*-----------------------*/
int convertCharToNumber(char target[1])
{
int numbered = target[0] - 48;
return numbered;
}
int generateDataFromFile(){
//-- temped
int currentLine = 1;
int currentRow = 0;
//-----------------
FILE *fp;
char line[MAXSIZE];
fp = fopen("test.txt", "r");
if (fp == NULL)
{
fprintf(stderr, "%s\n", "Error reading from file");
exit(EXIT_FAILURE);
}
while (fgets(line, MAXSIZE, fp) != NULL)
{
if(hard_trace){ // if it was enabled
printf("current line : %d and length : %d\n", currentLine, strlen(line));
}
if (line[strlen(line) - 1] == '\n') // cutout the \n to make the txt easy to use
{
line[strlen(line) - 1] = '\0';
}
//appileToStruct(line,currentRow);
matrixs.A[currentRow] = line;
//if(trace) printf("%s\n", line);
currentLine++; currentRow++;
}
if(trace) printf("Total line receive from txt file : %d\n" , currentLine-1); //if it was enabled
fclose(fp);
// ----------- assign the var
matrixs.depth = currentLine - 1;
//----------------------------
//return 1;
}
void main(){
generateDataFromFile();
printf("Total : %d TXT : [%s]", strlen(matrixs.A[0]), matrixs.A[0]);
}
以及此处的输出
从txt文件接收的总行数:3
总数:10 TXT:[]
。
但是当我直接将代码放在这样的主体中
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
//------Options -- change only true / false to trigger the function
bool hard_trace = false;
bool trace = true;
/*-------------------*/
//---------Defines----------
#define MAXSIZE 100 // maximum size of the characters in txt file to be buffed
/*----------------------*/
//---------Structs-----------
struct Matrix
{
char *A[10];
int depth;
};
/*--------------------------*/
//-----Variable----------
//-- global
char *B[3];
//- struct
struct Matrix matrixs; // create new global struct
//-
//--
/*-----------------------*/
int convertCharToNumber(char target[1])
{
int numbered = target[0] - 48;
return numbered;
}
int main()
{
//-- temped
int currentLine = 1;
int currentRow = 0;
//-----------------
FILE *fp;
char line[MAXSIZE];
fp = fopen("test.txt", "r");
if (fp == NULL)
{
fprintf(stderr, "%s\n", "Error reading from file");
exit(EXIT_FAILURE);
}
while (fgets(line, MAXSIZE, fp) != NULL)
{
if (hard_trace)
{ // if it was enabled
printf("current line : %d and length : %d\n", currentLine, strlen(line));
}
if (line[strlen(line) - 1] == '\n') // cutout the \n to make the txt easy to use
{
line[strlen(line) - 1] = '\0';
}
//appileToStruct(line,currentRow);
matrixs.A[currentRow] = line;
//if(trace) printf("%s\n", line);
currentLine++;
currentRow++;
}
if (trace)
printf("Total line recieve from txt file : %d\n", currentLine - 1); //if it was enabled
fclose(fp);
// ----------- assign the var
matrixs.depth = currentLine - 1;
//----------------------------
printf("Total : %d TXT : [%s]", strlen(matrixs.A[0]), matrixs.A[0]);
}
输出
从txt文件接收的总行数:3
总计:10 TXT:[0000111100]
您能向我解释为什么第一个代码不起作用吗,我的意思是为什么printf中的%s不能为我显示输出以及我如何才能使第一个代码正常工作
答案 0 :(得分:0)
这就是原因:matrixs.A[currentRow] = line;
。
line
在第一种情况下是该函数的本地函数。该语句分配了指针,它不会复制字符串(您应该使用strncpy
,并且不要忘记通过malloc
分配所需的内存空间),因此当一切都在main()
中,line
在该范围内得到了很好的定义,因此matrixs.A[0]
是指向现有line
的指针,而在第一种情况下,行是属于的本地数组generateDataFromFile()。
当您尝试从matrixs.A[0]
打印main()
时(在第一种情况下),您会调用未定义的行为,因为您正在执行违反堆栈的行为并尝试访问堆栈上的某个地址,该地址可能包含流程执行时所需的任何内容。
建议的解决方法:
// instead of matrixs.A[currentRow] = line
size_t lineSize = strlen(line)+1;
matrixs.A[currentRow] = malloc(lineSize);
strncpy(matrixs.A[currentRow], line, lineSize);
别忘了最后free()
分配的内存。
答案 1 :(得分:0)
执行此操作时:
matrixs.A[currentRow] = line;
您正在将本地数组line
的地址分配给matrixs.A
的元素。在第二个程序的情况下,由于line
仍在作用域内,因此它会打印有效值。但是在第一个程序中,line
超出范围,因此matrixs.A[0]
指向无效的内存。取消引用此指针将调用undefined behavior。
此外,在第二个程序中,您可能会注意到matrixs.A
的每个元素都包含您读取的最后一个值。再次是因为您要在每个地址中存储line
的地址。
您应该对所读取的字符串进行复制,并保存指向新字符串的指针。这样,1)您没有存储局部变量的地址,2)您没有在matrixs.A
的每个元素中存储相同的地址。
matrixs.A[currentRow] = strdup(line);