【问题标题】:scanning from an input file in C until reaching a certain character (#)?从 C 中的输入文件扫描直到到达某个字符 (#)?
【发布时间】:2013-08-14 00:34:01
【问题描述】:

简单的问题:

如果我在输入文件中有一行看起来像:

Hello#Great#Day#Today

如何将每个单词单独扫描为自己的数组,换句话说,告诉 C 在到达 # 字符时停止扫描,然后进入循环的下一次迭代以将下一个单词扫描为单独的数组?

【问题讨论】:

  • 我先写一个算法(检查),然后写一些代码。如果这不起作用,请把它带到这里,我们会看看我们能做些什么来提供帮助。
  • 抱歉,我只是认为让比我更有经验的人向我展示实现此功能的方法会很简单,但我想解决方案比我想象的要复杂。
  • 这里是一个kickstart。 1. 查找文件的大小(参见fseek()ftell())。 2. 为整个文件分配一个足够大的缓冲区 +1 用于空终止符(请参阅malloc())。 3. 将整个文件读入缓冲区(参见freed())。 4. 在缓冲区的end 处设置0 终止符。最后,使用"#" 作为分隔符,使用strtok() 循环缓冲区。完成后,不要忘记释放 just 在上面 (2) 中分配的原始内存块。查找刚才提到的所有 API 并制定您的计划。祝你好运。
  • 注意。那应该是 fread() 。我总是这样做。对不起!。

标签: c arrays loops input terminate


【解决方案1】:

这是假设您正在阅读stdin。一定要看看@Whoz kick start 方法(与此非常相似)。


您想要做的是创建一个动态数组并用通过stdin 读取的每个字节填充它。然后,您需要创建一个字符指针数组,该数组将指向每个“单词”中的第一个字符,您可以在其中将单词定义为 '#' 字符(分隔符)之前的每个字符。然后,您将遍历该字符数组并使用每个单词中第一个字符的内存地址填充字符指针数组。

【讨论】:

  • "...arr 只指向每个单词的第一个字符。" 不,它没有。这将循环范围变量的地址(byte 存储在 char 数组中。一旦循环退出,取消引用此指针是未定义的行为。如果要这样做,则需要一个完整文件将每个# 替换为0 的缓冲区会好得多(更不用说,使您的进程崩溃的可能性要小得多)。
  • @WhozCraig,我现在意识到我的解决方案有多么错误——不知道我在想什么。固定。
  • 那好多了。你的回答和 Magn3s1um 一起基本上说明了我在一般评论中提到的 kickstart。
  • @WhozCraig,哦,我没有注意到你之前提到过这种方法。我会记下来的。
【解决方案2】:

使用 strtok() 按指定字符标记您的输入。

http://www.cplusplus.com/reference/cstring/strtok/

 char str[] ="- This, a sample string.";
 char * pch;
 printf ("Splitting string \"%s\" into tokens:\n",str);
 pch = strtok (str,"#");
  while (pch != NULL)
 {
 printf ("%s\n",pch);
 pch = strtok (NULL, "#");
}

【讨论】:

    【解决方案3】:

    在两个阶段,我使用了这样的东西:

    #include <ansi_c.h>
    
    //tokenizing a string
    int GetCount(char *in, char *delim, int *m);
    int GetStrings(char *in, char *delim, int count, char **out);  
    
    
    void main(void)
    {
        int count, maxlen, i;
        char inpString[]={"Hello#Greatest#Day#Today"};
        char *resultBuf[10];
    
        //get a count of strings to store
        count = GetCount(inpString, "#", &maxlen);
    
        for(i=0;i<10;i++)
        {
            resultBuf[i] = calloc(maxlen+1, sizeof(char));  
        }
    
        //Store strings in arrays
        GetStrings(inpString, "#", count, resultBuf);
    
        for(i=0;i<count;i++)
        {
            printf("%s\n", resultBuf[i]);
            free(resultBuf[i];
        }             
    
    }
         //Gets count of tokens (delimited strings)
    int GetCount(char *in, char *delim, int *m)
    {
        char *buf=0;
        char temp1[10]={0};
        char *inStr;
        int count = 0;
        int max = 0, keepMax = 0;
        if(in)
        {
    
            inStr = calloc(strlen(in)+1, sizeof(char));
            strcpy(inStr, in);
            if(strlen(inStr) > 1)
            {
                count = 0;
                buf = strtok(inStr, delim);
                while(buf)
                {
                    strcpy(temp1, buf);
                    max = strlen(temp1);
                    (max > keepMax)?(keepMax = max):(keepMax == keepMax);
                    count++;
                    buf = strtok(NULL, delim);
                }
                *m = keepMax;
            }
            free(inStr);
        }
        return count;
    }
         //Gets array of strings
    int GetStrings(char *in, char *delim, int count, char **out)
    {
        char *buf=0;
        char *inStr;
        int i = 0;
        if(in)
        {
    
            inStr = calloc(strlen(in)+1, sizeof(char));
            strcpy(inStr, in);
            if(strlen(inStr) > 1)
            {
                buf = strtok(inStr, delim);
                while(buf)
                {
                    strcpy(out[i], buf);
                    buf = strtok(NULL, delim);
                    i++;
                }
            }
            free(inStr);
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 2020-09-07
      相关资源
      最近更新 更多