0

我一直在开发一个程序,我需要使用 C 来扫描文件中的行并将它们存储在结构中。

我的 .txt 文件格式为:

NAME 0.2 0.3
NAME2 0.8 0.1

或者一般来说它是一个字符串,后跟 2 个双打

我的结构是:

struct device {
char* name;
double interruptProbability, interruptTime, startTime, endTime;
} myDevice;

现在,我可以很好地扫描这些行,但是当需要将它们放入我的结构中时,有些事情就搞砸了。这是我进行扫描的方式:

    char line[BUFSIZ];
    while(fgets (line, BUFSIZ, devicesFile) != NULL){
        struct device *d = &myDevice;
        if(!isspace(*line)){
            printf("String: %s \n", &line);
            d->name = "success"; // for testing purposes
            printf("device name before: %s \n", d[0]);
            sscanf(line, "%s %f %f",&d->name, &d->interruptProbability, &d->interruptTime);
            printf("device name after: %s \n", d[0]);
        }
    }

当我运行它时,它会打印出来:

String: Disk 0.2 0.00005


device name before: success 

在给我一个段错误之前。

我运行 GDB 来测试扫描发生了什么,无论出于何种原因,它都会在 d->name 中放入一个巨大的十六进制数字,该数字旁边有(地址越界)。

有任何想法吗?

4

4 回答 4

1

这是因为您在sscanf调用中覆盖了文字字符串。d->name指向一个文字字符串,它们是只读的且具有固定长度(因此,如果您尝试获取的字符串长度超过 7 个字符,您也可以尝试将其写入末尾)。

您需要使用数组d->name或在堆上为其分配内存。

于 2013-02-07T03:26:16.587 回答
0

您没有为每个char *name. 您需要d->name = (char *)malloc(<length of the token>*sizeof(char)+1)在 sscanf 调用之前添加。

于 2013-02-07T03:29:48.843 回答
0

您不能将字符串扫描到指针d->name中。

即使在您为其分配了一个常量值之后:

d->name = "success"; // for testing purposes

您需要为其分配内存,或将其设为数组。您应该非常小心地使用sscanf来读取字符串。使用strtok或只是strchr找到第一个空格然后用 . 复制字节可能会更好strdup

char *next = strchr(line, ' ');
if( next != NULL ) {
    *next++ = 0;             // Terminate string and move to next token.
    d->name = strdup(line);  // Make a copy of tokenised string

    // Read the floats - note you should check that the result is equal to 2.
    count = sscanf(next, "%f %f", d->interruptProbability, d->interruptTime);
}
于 2013-02-07T03:30:22.857 回答
0

您正在扫描字符串文字。字符串文字在 C 和 C++ 中是 const char*s,是只读的,因此 sscanf 在尝试写入字符串文字“成功”时会崩溃。

于 2013-02-07T03:30:28.890 回答