【问题标题】:Unexpected result on string parsing with C language使用 C 语言解析字符串时出现意外结果
【发布时间】:2013-01-24 11:22:31
【问题描述】:

我有以下(简化的)使用 line 构建的简单应用程序:

gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -D_GNU_SOURCE      -D_XOPEN_SOURCE -std=c99 -ggdb -O0 main-test.c -L/usr/lib -lm -lglib-2.0 -o main-test

应用程序本身:

#include <stdio.h>
#include <ctype.h>
#include <alloca.h>
#include <glib.h>
#include <glib/gprintf.h>
#include "main.h"

const char *filter(char *original, pt_search_key key) {
    const char *mname = "ModelName";
    const char *pname = "Product";
    const char *delim = " \t";
    const char *delim_str = "\"";
    const char *end = "\n";
    char *value = NULL;
    char *token;
    char *copied = malloc(sizeof(original)+1);
    strcpy(copied, original);

    // Just delete initial tabs and whitespaces
    while(isblank(*copied)) {
        copied++;
        continue;
    }

    token = strsep(&copied, delim);
    if (!strcmp(token, mname))
    {
        token = strsep(&copied, delim_str);
        if(!strcmp(token, "")) {
            token = strsep(&copied, delim_str);

            printf("[before] Token: %s\n", token);
            printf("[before] Value: %s\n", value);
            //*********** Strange behaviour is here!!! *****//
            value = malloc(strlen(token)+1);
            printf("[after] Token: %s\n", token);
            printf("[after] Value: %s\n", value);

            strcpy(value, token);
            token = strsep(&copied, end);
            while(*token != '\0') {
                if(isblank(*token)) {
                    token++;
                    continue;
                } else {
                    printf("String contains unexpected symbols:\n");
                    printf("%s\n", original);
                    exit(EXIT_FAILURE);
                }
           }
        } else {
              printf("String which contains %s is not correct", original);
              exit(EXIT_FAILURE);
        }
    }
return value;
}

int main(int argc, char **argv)
{
    filter("  ModelName \"Business Inkjet 1000\"\n", PT_MODELNAME);
    return EXIT_SUCCESS;
}

此应用程序给出以下结果:

./main-test 
[before] Token: Business Inkjet 1000
[before] Value: (null)
[after] Token: Business In!
[after] Value: 0

我完全误解了为什么 token 已更改。对我来说,token 的输出应该是:"Business Inkjet 1000"哪里出错了?

【问题讨论】:

  • 每个字符串都在某个时刻以空结尾,通常是结尾;你也在使用 C 类型的字符串

标签: c linux parsing unix


【解决方案1】:

我认为这只是一个错字,但sizeof(original) 在这种情况下只是指针的大小。

  char *copied = malloc(sizeof(original)+1);   ??

你需要:

  char *copied = malloc(strlen(original)+1);

【讨论】:

  • 谢谢!我盯着这段代码看了很长时间,却找不到问题所在。这是我的错。
  • 这是否意味着在我的情况下我超出了分配内存的范围(因为 copied 是 sizeof(original) + 1 = 8 + 1 bytes 对于 64 位系统)并重写一些其他内存?这就是为什么我会得到这个奇怪的结果 - 在malloc() 之后修改了token
猜你喜欢
  • 2022-01-01
  • 2020-10-20
  • 1970-01-01
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 2022-11-05
  • 2011-10-26
相关资源
最近更新 更多