【问题标题】:Parsing contents of a textfile in C(Deleting parts, storing others)用C解析文本文件的内容(删除部分,存储其他部分)
【发布时间】:2016-04-25 17:18:23
【问题描述】:

我有一个基本的 .txt 文件,其中可能包含未知数量的完全采用这种格式的数据,我需要提取 '=' 标识符之后的第二部分。例如:

variable1=Hello
variable2=How
variable3=Are
variable4=You?

我需要提取“Hello”“How”“Are”和“You?”分别并将它们存储到一个数组中(删除/忽略变量名)并能够单独调用每个单词。我在 C 中做这个,这就是我目前拥有的。

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

int main()
{
    char*result;
    char copy[256];
    FILE * filePtr;
    filePtr = fopen("testfile.txt", "r+");

    strcpy(copy, "testfile.txt");
    while(fgets(copy, 256, filePtr)!= NULL)
    {
      result = strchr(copy, '=');
      result = strtok(NULL, "=");
      printf("%s",result);
      if(result != 0)
      {
        *result = 0;
      }
    result = strtok(copy, "=");
    }
return 0;
}

我目前的输出是

(null)How
Are
You?

【问题讨论】:

    标签: c parsing strtok


    【解决方案1】:
    • 你不需要strtok,使用strchr就足够了。
    • 无需将文件名复制到copy 缓冲区。
    • 可能也不需要以更新模式打开文件"%r+"

    这是一个更正的版本:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void) {
        char *words[20];
        int n = 0;
        char *result;
        char copy[256];
        FILE *filePtr;
        filePtr = fopen("testfile.txt", "r");
    
        while (fgets(copy, 256, filePtr) != NULL) {
            copy[strcspn(copy, "\n")] = '\0';  /* strip the \n if present */
            result = strchr(copy, '=');
            if (result != NULL) {
                words[n++] = strdup(result + 1);
                printf("%s ", result + 1);
            }
        }
        printf("\n");
        fclose(filePtr);
        return 0;
    }
    

    注意将copy 末尾的尾随\n 去掉fgets(): copy[strcspn(copy, "\n")] = '\0';。即使fgets() 在缓冲区结束之前或文件结束之前没有看到\n,它也可以工作。 strcspn 计数返回 copy 中不在第二个参数中的字符数,因此它返回没有 \n 的行的长度。

    单词被收集到字符串指针数组words 中。每个字都通过strdup 函数复制到malloc 分配的内存中。 strdup 不是标准 C 的一部分,而是 Posix 的一部分,并且可能存在于您的环境中,可能写为 _strdup

    还请注意,您还应该测试打开文件失败、在strdup 中分配内存失败以及处理超过20 的字符串...

    如果有一组固定的单词,而你只想去掉开头的部分,你可以使用更简单的硬编码方法:

    int main(void) {
        char word1[20], word2[20], word3[20], word4[20];
        FILE *filePtr;
        filePtr = fopen("testfile.txt", "r");
    
        if (fscanf(filePtr,
                   "%*[^=]=%19[^\n]%*[^=]=%19[^\n]%*[^=]=%19[^\n]%*[^=]=%19[^\n]",
                   word1, word2, word3, word4) == 4) {
            printf("%s %s %s %s\n", word1, word2, word3, word4);
            // perform whatever task with the arrays
        } else {
            printf("parse failed\n");
        }
        fclose(filePtr);
        return 0;
    }
    

    【讨论】:

    • 感谢您的快速回复,非常感谢,有几个问题:在第 14 行,strcspn 发生了什么,除了使用这个函数还有其他选择吗?其次,我将如何将每个单独的单词存储到它自己的数组中以便能够在其他地方使用这些单词?
    • @shrimpay:我更新了答案。单词存储在一个数组中,你可以在其他地方使用。您可能需要修改代码以处理更多单词,可能是任意数量,并且数组本身可能需要分配 malloc 以在您退出解析函数后持续存在。然后,您还应该返回计数或在数组末尾存储一个额外的 NULL 作为结束标记。
    • 我想我问错了问题,我试图将每个单词分别存储在单独的数组中,而不是全部存储在一个数组中。那么我可以指定"Hello" = var1[20]"How "= var2[20]。希望这是有道理的,我刚刚意识到我的问题要求将它们分开,但是将它们存储到同一个数组中,这不是我想要的。
    • 如果这是您的规范,那么您就知道要查找多少个字符串以及要将它们存储在哪里。代替word[n++] = strdup(result+1);,编写您自己的代码来存储第n 个字符串。
    • 我是 stackoverflow 的新手,所以不知道如何感谢您的宝贵时间。我给了你绿色支票。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 2017-11-04
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多