在C中动态分配的从文件读取的未知长度字符串(必须防止从文件中读取数字)

Posted

技术标签:

【中文标题】在C中动态分配的从文件读取的未知长度字符串(必须防止从文件中读取数字)【英文标题】:Dynamically allocated unknown length string reading from file (it has to be protected from reading numbers from the file) in C 【发布时间】:2020-09-07 20:55:30 【问题描述】:

我的问题是我需要从文件中读取字符串。文件示例:

示例 1 句

例句xd 595 xd 49 lol

但我必须只阅读字符串部分,而不是数字。我想我必须使用fscanf()%s,但请告诉我你们对此的看法。 我的问题开始的部分是如何使用malloc()realloc() 读取字符串(长度未知)?我自己尝试过,但失败了(我的解决方案在我的帖子底部)。 然后我需要在屏幕上显示结果。

附:我必须使用malloc()/calloc()realloc() char *)

我试过的代码:

    int wordSize = 2;
    char *word = (char *)malloc(wordSize*sizeof(char));
    char ch;

    FILE* InputWords = NULL;
    InputWords = fopen(ListOfWords,"r"); /* variable ListOfWords contains name of the file */

    if (InputWords == NULL)
    
      printf("Error while opening the file.\n");
      return 0;
    

    int index = 0;
    while((ch = fgetc(InputWords)) != -1)
    
      if(ch == ' ')
      
        printf("%s\n", word);
        wordSize = 2;
        index = 0;
        free(word);
        char* word = (char *)malloc(wordSize*sizeof(char));
      
      else
      
        wordSize++;
        word = (char *)realloc(word, wordSize*sizeof(char));
        strcpy(word,ch);
        index++;
      
    
  fclose(InputWords);

【问题讨论】:

不相关的建议:使用EOF(可以是任何负值)而不是-1 char ch: ==> int ch; 【参考方案1】:

对于您的代码,您有一些需要改进的地方:

    fgetc 返回 int 类型而不是 char。所以把char ch改成int ch; 作为@pmg 的注释,使用EOF(可以是任何负值)而不是-1` strcpy(word,ch); 您尝试将字符 (ch) 复制到字符指针 (word)。 不要强制转换mallocrealloc 函数:Do I cast the result of malloc?。

为了解决您的问题,我建议您使用strtok 函数按空格字符分割字符串,然后测试每个单词是否为数字。如果单词不是数字,可以使用strcat将单词连接到旧句子

完整代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int is_number(char *str) 
    if (strlen(str) == 0)
       return -1;
    for(int i =0; (i < strlen(str)) && (str[i] != '\n') ; i++) 
        if(!isdigit(str[i]))
            return -1;
    
    return 1;


int main()

    FILE *fp = fopen("input.txt", "r");
    char line[256];

    if(!fp) return -1;
    char **sentence;
    int i = 0;
    sentence = malloc(sizeof(char *));
    if(!sentence) return -1;
    while(fgets(line, 256, fp)) 
        char * token = strtok(line, " ");
        size_t len = 0;
        sentence = realloc(sentence, sizeof(char *) * (i+1));
        if(!sentence) return -1;
        while(token != NULL) 
            if (is_number(token) != 1) 

                sentence[i] = realloc(sentence[i], len + 2 + strlen(token)); // +2 because 1 for null character and 1 for space character
                if (!sentence[i]) 
                    printf("cannot realloc\n");
                    return -1;
                
                strcat(strcat(sentence[i], " "), token);
                len = strlen(sentence[i]);
            
            token = strtok(NULL, " ");
        
        if(len > 0)
           i++;
    

    for(int j = 0; j < i; j++) 
        printf("line[%d]: %s", j, sentence[j]);
    

    for(int j = 0; j < i; j++) 
        free(sentence[j]);
    
    free(sentence);
    fclose(fp);
    return 0;


输入输出:

$cat input.txt
Example 1 sentence
Example sentence number xd 595 xd 49 lol

./test

line[0]:  Example sentence                                                                                                                                  
line[1]:  Example sentence number xd xd lol

【讨论】:

我会在晚上测试它并给你反馈。无论如何,您的解决方案似乎是合法的 @Cris 正如您在我的回答中看到的,我已经用您的输入对其进行了测试。我的答案中的输出是你想要的? "cannot realloc" 一直出现。任何想法为什么会这样? @Cris 您是否正确复制并粘贴了我的代码?它使用在线编译器onlinegdb.com/HkXzR38jI 它也适用于我的电脑。尝试复制并粘贴代码。

以上是关于在C中动态分配的从文件读取的未知长度字符串(必须防止从文件中读取数字)的主要内容,如果未能解决你的问题,请参考以下文章

c++中用new给未知大小的数组分配空间怎么弄?

C - 未知维度的2D游戏板的动态分配

动态分配许多小块内存

C - 读取文件并将文本放入具有动态内存分配的字符指针

C语言试题184之编写一个函数,从标准输入读取一个字符串,把字符串复制到动态内存分配的内存中,并返回该字符串的拷贝,这个函数不应该对读入字符串的长度作任何限制

C语言试题184之编写一个函数,从标准输入读取一个字符串,把字符串复制到动态内存分配的内存中,并返回该字符串的拷贝,这个函数不应该对读入字符串的长度作任何限制