C语言 从文本文件中获取单词到数组

jdgnovmf  于 2023-06-05  发布在  其他
关注(0)|答案(4)|浏览(188)

我的文本文件格式如下:

my.txt
Red
Green
Blue
Yellow

我特灵着用这样的词:

typedef char * string;
main(){
   int i;
   string array[4];

   FILE *my;
   my = fopen("my.txt","r");
   for(i = 0; i < 4; i++)
         fscanf(data, "%s", &array[i]);
   fclose(my);
}

当我尝试打印数组时,出现错误。我的代码出了什么问题,如何修复?

ie3xauqp

ie3xauqp1#

您需要为以null结尾的字符串分配内存。
目前,你只为4个char *分配内存,但是这些指针没有初始化,因此当你试图向它们指向的内存写入数据时,会导致 UB(未定义行为)。

工作示例片段

在下面的代码片段中使用“%127s”是为了防止我们在分配的内存范围之外写入。对于我们正在讨论的 format-string,我们将最多读取/写入127字节+空终止符。
请记住,如果要在“真实的生活”中使用,则应实施进一步的错误检查。

  • 尝试打开文件后,检查file_handle是否确实有效
  • 检查malloc是否确实分配了请求的内存
  • 检查fscanf是否读取了所需的输入
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int
main (int argc, char *argv[])
{
  int i;
  char * lines[4];
  FILE *file_handle = fopen ("my.txt", "r");

  for (i =0; i < 4; ++i) {
    lines[i] = malloc (128); /* allocate a memory slot of 128 chars */
    fscanf (file_handle, "%127s", lines[i]);
  }

  for (i =0; i < 4; ++i)
    printf ("%d: %s\n", i, lines[i]);

  for (i =0; i < 4; ++i)
    free (lines[i]); /* remember to deallocated the memory allocated */

  return 0;
}

输出

0: Red
1: Green
2: Blue
3: Yellow
uz75evzq

uz75evzq2#

你试图读取一些数据,但你没有地方可以放它。你所拥有的只是4个指针,指着天知道在哪里,而你正试图写进去!
有很多方法可以做到这一点:
1.你知道数据大小的界限:

#include <stdio.h>

#define MAX_CHARS 20

typedef char string[MAX_CHARS+1];  // leave one space for '\0'

main(){
   int i;
   string array[4];

   FILE *my;
   my = fopen("my.txt","r");
   for(i = 0; i < 4; i++)
         fscanf(data, "%s", array[i]);  // no need for & with %s
   fclose(my);
}

1.假设数据的大小有一个绑定,并忽略其余的字符串(如果它太大):

#include <stdio.h>

#define MAX_CHARS 20
#define MAX_CHARS_STR "20"  // there are better ways to get this

typedef char string[MAX_CHARS+1];

main(){
   int i;
   string array[4];

   FILE *my;
   my = fopen("my.txt","r");
   for(i = 0; i < 4; i++){
         fscanf(data, "%"MAX_CHARS_STR"s", &array[i]);  // read at most 20 chars for the string
         ungetc('x', data);     // append one character to make sure we don't hit space
         fscanf(data, "%*s");   // ignore whatever is left of string
   }
   fclose(my);
}

1.读取文件两次,第一次找出每个字符串的大小(或最大大小,为简单起见),然后为字符串分配内存(使用malloc)。然后再次读取文件,这次实际存储字符串:

#include <stdio.h>

typedef char *string;

main(){
   int i;
   string array[4];
   int cur_size = 0;

   FILE *my;
   my = fopen("my.txt","r");
   for(i = 0; i < 4; i++){
         fscanf(data, "%*s%n", &cur_size);
         array[i] = malloc((cur_size+1)*sizeof(*array[i]));
   }
   fclose(my);

   my = fopen("my.txt","r");
   for(i = 0; i < 4; i++){
         fscanf(data, "%s", array[i]);
   }
   fclose(my);

   // and when done:
   for(i = 0; i < 4; i++){
         free(array[i]);
   }
}

1.从输入中逐块读取。对于每个字符串,如果输入字符串尚未完成,则调整为字符串分配的内存大小(增加其大小),读取另一个块并再次检查。方法3更快,我推荐它,但你要知道,这基本上是C++的string中发生的事情。

osh3o9ms

osh3o9ms3#

因为所有其他的答案都告诉你你做错了什么,而不是如何修复它。这里

typedef char * string;
#define LEN 100 //long enough for your line
main(){
   int i;
   string array[4];

   for(i = 0; i < 4; i++) {
      if((array[i] = (char *)(malloc(sizeof(char) * LEN))) == NULL) {
          printf("malloc failed");
          return 1;
      }
   } 

   FILE *my;
   my = fopen("my.txt","r");
   for(i = 0; i < 4; i++)
         fscanf(data, "%s", &array[i]);
   fclose(my);
}

就像他们说的,你为指针腾出了空间,但没有为指针指向的东西腾出空间。

nwsw7zdq

nwsw7zdq4#

第一步是获取文本文件中的行数,然后初始化一个字符串数组,其大小与文本文件中的行数相同,然后以编程方式循环所有行,同时将每行上的单词分配给数组中相应的索引,如下面的代码所示。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>



int main() {
    //Declare the file pointer
    FILE* dictionary = fopen("data.txt", "r");
    //check if the file is null and return an exit code to the OS
    if (dictionary == NULL) {
        printf("%s", "Unable to open the file");
        return 909;
    }
    else {
        //initialize a variable for counting the number of words in the file
        int count = 0;
        //maximum length of each word in the text file is 30
        char word[30];
        //use fgets to count the number of words in the text file
        while (fgets(word, sizeof(word), dictionary) != NULL) {
            count++;
        }
        //initialize a string array with the count as the size
        char  words[count][30];
        //declare an integer for traversing the array
        int index = 0;
        //reset the file pointer to the beginning of the file for a second reading process
        fseek(dictionary, 0, SEEK_SET);
        while (fgets(word, sizeof(word), dictionary)!=NULL) {
            //assign word to each own index in our array
            strcpy(words[index], word);
            index++;
            
        }
        for(int i=0;i<count;i++){
            printf("%s ",words[i]);
        }
    }
    return 0;
}

相关问题