如何使用分隔符使用fscanf扫描文本文件?

时间:2013-07-26 08:12:14

标签: c text delimiter scanf

这就是文件中文本的样子:

    locked y
    locked n
    position 90
    position 2
    audio-language "english"
    audio-language "spanish"

每个文本文件只包含上面显示的一种设置,区别在于选项(y或n,1到999,“英语”“西班牙语”“其他任何”)它前面有4个空格和一个每行末尾的新行,所以我需要一个fscanf,它将在char数组字符串中提取参数,但我似乎无法理解如何正确使用分隔符。我必须制作一个程序,可以扫描该文件并打印不同的设置以及在文件中找到它们的次数,例如:

audio-language is found with setting: "spanish" 40 times

audio-language is found with setting: "english" 78 times

比你们所有人的答案都要好!在这里,我可以告诉你我是如何工作的:

1 - 首先你使用一个功能(我在互联网上找到)消除了设置前面的空白区域:

char* ltrim(char* s) 
{
    char* newstart = s;

  while (isspace( *newstart)) {
    ++newstart;
   }

   // newstart points to first non-whitespace char (which might be '\0')
   memmove( s, newstart, strlen( newstart) + 1); // don't forget to move the '\0' terminator

return s;
 }

2 - 然后fscanf没有问题,让线路正确:

while(!feof(fpoo)) {
    fscanf(fpoo,"%s %[^\n]",&first, &sec);

3 - 然后你将fscanf得到的那些与用户输入的那些进行比较

就是这样,显然 fscanf 的整个问题是因为每行前面都有空格。

4 个答案:

答案 0 :(得分:2)

我编译了这段代码并对其进行了测试。完美的工作。你也可以测试它:))

int main()
{
    int bytes_read = 0, english_count = 0, spanish_count = 0;
    char file_buffer[256], setting[127], option[32], fileName[32] = "FileName.txt";
    FILE *fp;
    if((fp = fopen("FileName.txt", "rb")) <=0)
    {
       printf("Unable to open the File\n");
    }
    //rewind(fp);
    while(fgets (file_buffer, 50, fp))
    {
       sscanf(file_buffer,"%s %s",setting,option);
       printf("Setting: ");
       printf("%s",setting);
       printf("\nOption: ");
       printf("%s",option);
       printf("\n\n");
       if(memcmp(setting,"audio-language",14) == 0)
       {
           if(memcmp(option,"english",7) == 0)
           {
               english_count = english_count+1;
           }
           if(memcmp(option,"spanish",7) == 0)
           {
               spanish_count = spanish_count+1;
           }
       }
           //you can add more checks here.
      }
    printf("\naudio-language is found with setting: english ");
    printf("%d",english_count);
    printf("\naudio-language is found with setting: spanish ");
    printf("%d",spanish_count);
    printf("\n");

return 0;
}

答案 1 :(得分:0)

检查算法,你必须编码

  1. 逐行读取文件,g表示每次1024字节。
  2. 然后扫描您想要的行,例如音频语言“english”或音频语言“spanish”。
  3. 获取语言类型的字符串
  4. 然后计算你找到这条线的次数。
  5. 我认为这可以解决您的问题。

答案 2 :(得分:0)

您可以先将字符串读入:

scanf("%[^\n]s",buffer)

现在,您可以使用C中的标记生成器通过 strtok

获取语言的值
char *token="\n";
token = strtok(line, token);

现在,令牌将包含所有拆分字,您可以将strcmp与可能的语言进行比较并保持计数

答案 3 :(得分:0)

您评论中的人是对的。你真的应该向我们展示你的尝试。如果这是家庭作业,那么你就不能作弊,因为你的讲师可能会通过简单的谷歌搜索来破坏你。期望我们在这里猜测你的理解并涵盖你已经涵盖的内容是浪费的,所以告诉我们你做了什么。

qsortbsearchstrcmp提供了一种简单,相对有效的排序&amp;搜索机制,用于以字符串开头的任何内容(例如,以字符串为前缀的结构)。格式字符串中的空格告诉fscanf消耗尽可能多的空格。 fscanf返回一个指示成功和失败模式的值,这意味着您不一定需要将每行读入一个字符数组,以测试输入是否与特定格式匹配。但是,您需要注意设计文件,以便所有命令都没有其他命令的公共前缀。在这种情况下,你是安全的。

这是我的尝试。快乐的调试:)

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

struct language_table { char language[64]; size_t count; };
struct language_table *parse(FILE *f, size_t *s);

int main(void) {
    size_t s;
    struct language_table *t = parse(stdin, &s);

    while (s-- > 0) {
        printf("audio-language is found with setting: %s %zu times\n", t[s].language, t[s].count);
    }

    free(t);
}

struct language_table *parse(FILE *f, size_t *s) {
    char locked, language[64];
    unsigned int position;

    int c = 0;

    struct language_table *table = NULL, *entry;
    size_t size = 0;

    do {
        if (fscanf(f, " locked %c", &locked) == 1 && strchr("ynYN", locked)) {
            /* XXX: Do something with locked. */
        }
        else if (fscanf(f, " position %u", &position) == 1) {
            /* XXX: Do something with position. */
        }
        else if (fscanf(f, " audio-language %63s", language) == 1) {
            /* search for the language in table. */
            entry = bsearch(language, table, size, sizeof *table, strcmp);

            /* insert the language if it's not found. */
            if (entry == NULL) {
                if ((size & (size + 1)) == 0) {
                    void *new = realloc(table, (size * 2 + 1) * sizeof *table);
                    if (new == NULL) {
                        fprintf(stderr, "failed to allocate new entry for %s\n", language);
                        free(table);
                        return NULL;
                    }
                    table = new;
                }

                entry = table + size++;
                strcpy(entry->language, language);
                entry->count = 0;

                /* sort & search */
                qsort(table, size, sizeof *table, strcmp);
                entry = bsearch(language, table, size, sizeof *table, strcmp);
            }

            entry->count++;
        }
        else {
            /* consume an invalid line */
            do {
                c = fgetc(f);
            } while (c >= 0 && c != '\n');
        }
    } while (c >= 0);

    *s = size;
    return table;
}