简体   繁体   English

尝试从文本文件读取数据时出现问题

[英]Issue while trying reading data from a text file

I'm trying to read data from a text file, and I'm trying to put each line of the text in a pointer to char . 我正在尝试从文本文件中读取数据,并且试图将文本的每一行放在指向char的指针中。 I created char* ligne[nl]; 我创建了char* ligne[nl]; where nl is the number of text lines. 其中nl是文本行数。

The issue is that when I try to print each ligne[] of the text, I found out that the ligne values have only the last line and not all the lines of the text. 问题是,当我尝试打印文本的每个ligne[]时,我发现ligne值仅包含文本的最后一行,而没有所有行。 Take a look at the code: 看一下代码:

First my file text contains these lines: 首先,我的文件文本包含以下几行:

mama
kaka
sasa

I'm using CodeBlocks C, and the code is: 我正在使用CodeBlocks C,代码是:

int main(void) {
    int i=0 ,k;
    char *ligne[3] = {NULL}; // three char pointer that take each ligne
    char word[25] = "";

    FILE* file = fopen("dico.txt", "r");

    if(file != NULL){
        while (fgets(word, 25, file) != NULL ){
            ligne[i] = word;
            i++;
        }

        // print each ligne of the file text
        for( i =0 ; i < 3 ; i++){
            printf("%s" , ligne[i]);
            printf("\n");
        }
    }
    return 0;
}

And the result of printing ligne[i] is: 打印ligne[i]的结果是:

sasa
sasa
sasa

instead of: 代替:

mama
kaka
sasa

What am I doing wrong? 我究竟做错了什么?

The problem is that you are making each index in the ligne array point to the word array. 问题是您要使ligne数组中的每个索引都指向单词数组。 So, when you are done with the fgets while loop, all the indices will be pointing to the data inside the word array, which is sasa (since this was the last word put into the word array, ie, you overwrote the other words). 因此,当您完成fgets while循环时,所有索引都将指向单词数组内的数据,这就是sasa(因为这是单词数组中的最后一个单词,即您覆盖了其他单词) 。 A possible solution is to declare your ligne array as follows: 一种可能的解决方案是如下声明您的ligne数组:

char ligne[4][25] . char ligne[4][25]

Then call fgets as such : 然后这样调用fgets:

fgets(ligne[i], 25, file)

On each round of the while loop. 在while循环的每一轮上。

The problem is that you always read the next word into "word" and you make all your ligne[i] elements point to the same variable, "word". 问题是您总是将下一个单词读入“ word”,并且使所有ligne [i]元素都指向相同的变量“ word”。 If you really do know the size of the words and the number of lines you can do: 如果您确实知道单词的大小和行数,则可以执行以下操作:

 int main( int argc, char **argv ) {
     int i=0 ,k;
     char ligne[4][25]; // three char pointer that take each ligne

     FILE* file = fopen("dico.txt" , "r");

     if(file != NULL){
         while ( fgets(ligne[i] , 25 , file) != NULL ) {
             i++;
         }

// print each ligne of the file text

     for( i =0 ; i < 3 ; i++){
         printf("%s" , ligne[i]);
         printf("\n");
         }
     }  return 0; 
}

Note that ligne is declared for 4 rows. 请注意,ligne声明为4行。 The reason is that after the 3rd line you still pass in ligne[4] to fgets, and even though fgets will return with NULL, the pointer you pass in should be valid. 原因是在第三行之后,您仍将ligne [4]传递给fgets,即使fgets将返回NULL,您传递的指针也应有效。

Also note that the code as is is very dangerous. 还要注意,这样的代码非常危险。 I relies on the file not having more than 3 lines, or more precisely, fgets returning NULL for the 4th call. 我所依赖的文件长度不超过3行,或更确切地说,fgets为第4次调用返回NULL。 These are not the same as the number of characters consumed in each call is limited to 24 (25-1) in each call. 这些与每次呼叫中消耗的字符数限制为每个呼叫中​​的24(25-1)个字符不同。 If that assumption fails then you'll have all sorts of interesting memory errors. 如果该假设失败,那么您将遇到各种有趣的内存错误。

You are overwriting the previously read value with any new reads. 您正在用任何新读取覆盖先前读取的值。 Debugging will show that each ligne element points to the same memory address. 调试将显示每个ligne元素都指向相同的内存地址。 Instead explicitly create a multi dimensional array and manually reference which element you want to assign to. 而是显式创建一个多维数组,然后手动引用要分配给哪个元素。

const unsigned int NUM_LINES = 3;
int i = 0;
char *ligne[3] = { NULL }; // three char pointer that take each ligne
char word[NUM_LINES][25];

FILE* file = fopen("dico.txt", "r");

if (file != NULL)
{
    while (fgets(word[i], 25, file) != NULL){
        ligne[i] = word[i];
        i++;
    }

    // print each ligne of the file text
    for (i = 0; i < 3; i++)
    {
        printf("%s", ligne[i]);
        printf("\n");
    }
}  
return 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM