【问题标题】:Why doesn't my Code work in Visual, but does in CodeBlocks?为什么我的代码在 Visual 中不起作用,但在 CodeBlocks 中起作用?
【发布时间】:2019-10-19 14:24:54
【问题描述】:

我正在尝试从文件中读取一些整数,但是在 Visual Studio Code 2013 中运行它时出现错误“调试断言失败!程序:...cuments\visual studio 2013\Projects.... \strtol.c 线路:94 表达式:nptr!=NULL

但是,相同的代码在 CodeBlocks 中运行良好。我最近才开始使用 Visual,所以我不太擅长。 这是我要阅读的文件的内容: 11 7 4 1 4 0 10 12 1 3 9

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


FILE *f;
void main(void) {
    int v[30], i = 0;
    char line[30], *p;
    f = fopen("Text.txt","r");

    fgets(line, 30, f);
    p = strtok(line, " ");
    v[i] = atoi(p);
    i++;
    while (p != NULL){
        p = strtok(NULL," ");
        v[i] = atoi(p);
        i++;
    }

    int n = i-1;
    for (i = 0; i < n; i++)
        printf("%d ", v[i]);

}

【问题讨论】:

  • 错误检查,总是错误检查!文件打不开怎么办?如果阅读失败怎么办?如果strtok 返回一个空指针怎么办?
  • 如果文件无法打开,f 可能为 NULL,strtok 可能会崩溃。如果第一行没有空格,strtok 将返回 NULL,atoi 可能会崩溃。尝试使用 Visual Studio 调试器单步执行代码并检查返回值,看看出了什么问题。也按照@Someprogrammerdude 的建议去做,并在代码本身中检查您的返回值。
  • Visual Studio CodeVisual Studio 2013 不是一回事,甚至不相关。 Visual Studio Code 不包括 Visual C++ 编译器。您使用的是什么编译器而不是什么 IDE?
  • 当这段代码在调试器中停止时(你在调试器中运行它对吗?),查看调用堆栈窗口以确定它在到达strtol() 之前在代码中的位置.

标签: c visual-studio-2013 file-read


【解决方案1】:

唯一可能导致strtol() 被调用的行是对atoi() 的调用——调试器中的调用堆栈会确认这一点。

两者都在这里:

p = strtok(line, " ");
v[i] = atoi(p);

这里:

    p = strtok(NULL," ");
    v[i] = atoi(p);

在将p != NULL 传递给atoi() 之前,您没有检查它。来自Microsoft's documentation

如果传入的参数为NULL,则无效的参数处理程序是 调用,如Parameter Validation 中所述。如果允许执行 要继续,这些函数将 errno 设置为 EINVAL 并返回 0。

对代码进行简单的重组将降低复杂性修复检查 NULL 失败的问题:

p = strtok(line, " ");
while (p != NULL)
{
    v[i] = atoi(p);
    i++;
    p = strtok(NULL," ");
}

代码总是错误的,但未定义的行为正是如此。这两个工具都包括一个调试器,Visual Studio 是最好的调试器,即使它的 C 支持停留在 1989 年。调用堆栈窗口将允许您观察调用函数的局部变量(在这种情况下为main()),并且你会看到p == NULL。真的;学习有效地使用调试器 - 比发布问题要快得多!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2018-04-24
    • 2019-01-07
    • 2014-04-28
    相关资源
    最近更新 更多