【问题标题】:Can sscanf in C write on char* instead of char[]?C中的sscanf可以写在char *而不是char []上吗?
【发布时间】:2016-06-29 20:28:55
【问题描述】:

我正在寻找标准 C 中解析字符串的最简单方法。字符串中的单词数量是固定的,但每个单词的长度不是固定的。代码将在内存有限的微处理器上运行,所以我不能只分配一个过度杀伤缓冲区,我想只分配我需要的内存。

以下代码有效,但我希望单个单词为 char* 。有没有办法解决这个问题?

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

int main(void) {

  char * my_words = "foo bar 1 2";

  char word1[20];
  char word2[20];
  char word3[20];
  char word4[20];

  int match = sscanf(my_words,"%s %s %s %s",word1,word2,word3,word4);

  printf("Matches: %d\r\n",match);

  printf("%s\r\n",word1);
  printf("%s\r\n",word2);
  printf("%s\r\n",word3);
  printf("%s\r\n",word4);

  return 0;
}

谢谢

【问题讨论】:

  • 你应该看看什么是数组,什么是指针。还要搜索“C 数组衰减到指针”。然后问问自己,你真正想在这里做什么。
  • 由于您在受限环境中运行:您可以使用malloc 吗?是否允许使用变长数组?
  • 最后想想以后是否需要源字符串,或者它的内存是否可以重用!
  • 在受限 MCU 上使用 scanfprintf 系列可能已经是个坏主意了。
  • 好吧,您可以将 char word1[20]; 替换为 char *word1 = malloc(20);,但这只会让您的代码更加冗长。

标签: c arrays pointers char scanf


【解决方案1】:

您可以使用strtok() 函数进行解析。一个简单的方法可以是这样的,你也可以修改它

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

int main(void) {

    char const *my_words = "foo bar 1 2";
    char *str = malloc(1 + strlen(my_words));
    strcpy(str, my_words);
    int countWord = 0;
    char * pch;
    printf ("Splitting string \"%s\" into tokens:\n",str);
    pch = strtok (str," ");
    while (pch != NULL)
    {
        printf ("%s\n",pch);
        pch = strtok (NULL, " ");
        ++countWord;
    }

    printf("Total words = %d\n", countWord);

    return 0;
}

【讨论】:

  • malloc(strlen(my_words)); --> malloc(strlen(my_words)+1);nul 终结符。
  • @snr: 或者char my_words[] = "foo bar 1 2" 然后就不需要复制了。
  • @BillLynch 当然,但我希望操作显示malloc 的简单用法,因为他提到了
  • strtok 可能不太适合 OP 的需要,因为 strtok 修改了它给出的字符串。
  • 直到他必须调试 SIGSEGV。 :)
【解决方案2】:

答案取决于您的代码应该有多简单和标准。

如果您的目标支持 POSIX 2008(最近的 GNU libc 支持),那么您可以使用 m 修饰符作为 docs suggest 来分配足够的空间来读取数据。

但如果您必须继续使用 ANSI C,那么您可能会被困在 strtok/strtok_r 之类的函数上。

【讨论】:

    【解决方案3】:

    如果您必须自己滚动,算法如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void) {
        /* your input, I'll presume its constant */
        const char *input = " foo  bar 1    2 ";
    
        /* here is your array of char*.
         * you indicate the number of words is fixed */
        char *words[4];
    
        /* the algo */
        size_t b = 0;
        size_t e = 0;
        size_t l = strlen(input);
        int w = 0;
        while (b < l) {
            b += strspn(input + b, " ");
            e  = b + strcspn(input + b, " ");
            words[w] = malloc(e - b + 1);
            strncpy(words[w], input + b, e - b);
            w++;
            b = e+1;
        }
    
        /* debugging, outputs in reverse order */
        while (w--) {
            printf("%s\n", words[w]);
            free(words[w]);
        }
    
        exit(EXIT_SUCCESS);
    }
    

    显然,您希望添加错误检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-31
      • 2012-03-26
      • 1970-01-01
      • 2017-05-07
      • 2020-07-17
      • 2015-07-25
      • 1970-01-01
      • 2016-04-25
      相关资源
      最近更新 更多