【问题标题】:printf doesn't always print correctlyprintf 并不总是正确打印
【发布时间】:2020-11-09 04:29:04
【问题描述】:

我知道这个问题在这里被问过好几次了。我遵循了初始化变量start (int start = 0) 之类的方法,或者在printf 语句中将其类型转换为int

但是这些方法没有帮助。所以我打开这个帖子再次问这个问题。

我的程序是从用户输入源字符串返回一个子字符串。我的方法有效。只有printf 不起作用。

我写了这个方法。

char *GetSubstring(const char source[], int start, int count, char result[])
{
    if ((size_t)start > strlen(source)) {
        *result = 0;
    } else {
        if ((size_t)(start + count) > strlen(source)) {
            count = strlen(source) - start;
        }
        while (start > 0) {
            source++;
            start--;
        }
        *(result + count) = 0;

        while ( count > 0 || *(source + count) != 0 ) {
            count--;
            *(result + count) = *(source + count);
        }
    }
    return(result);
}

如果我对所有参数进行硬编码,打印语句就可以正常工作。

int main(void)
{
    char source[100] = "abcdefg";
    char result[100];
    int start = 2;
    int count = 3;

    printf("%s %d %d\n", source, start, count); //all correct
    printf("%s %d %d %s\n", source, start, count,
           GetSubstring(source,start,count,result));//all correct

    return 0;
}

但是,如果我从用户输入中获取参数。第一个printf 语句中的“开始”打印正确。但它在第二个printf 语句中打印为垃圾。其他参数打印正确。

int main(void)    
{
    char source[100];
    char result[100];
    int start = 0;
    int count = 0;

    printf("enter source\n");
    fgets(source, 100, stdin);
    source[strcspn(source, "\n")] = '\0';

    printf("enter start and count\n");
    scanf("%d%d", &start, &count);

    printf("%s %d %d\n", source, start, count); //all correct
    //'start' print out as 1650524162, rest parameters correct
    printf("%s %d %d %s\n", source, start, count,
           GetSubstring(source,start,count,result));

    return 0;
}

问题可能与我的方法GetSubstring 中的类型转换(size_t)start 有关。但我需要这样做才能与strlen(source) 进行比较。

请告诉我任何建议。谢谢。

【问题讨论】:

  • 确保在将子字符串输入 printf 之前使用 '\0' 字符终止子字符串
  • (size_t)start - 呃,不要做这样的演员。
  • 演员表在这里不是问题,但它们表明另一个问题。纠正它的正确方法不是强制转换,而是制作 startcount 类型为 size_t
  • @KiJéy, *(result + count) = 0; 这样做。

标签: c substring


【解决方案1】:

问题不在于size_t 转换,尽管您可以将这些变量设为size_t 并完全避免转换,like @klutt sugested,并在printfscanf 中使用%zu 格式说明符。

你抱怨的问题在于这个循环:

while ( count > 0 || *(source + count) != 0 )
{
     count--;
     *(result + count) = *(source + count);
     printf("%s %d %d\n", source, start, count);
}

当您在条件中使用|| 时,count 将被允许为负数,这在术语中允许对source 进行负索引,这在术语中调用未定义的行为。

另一个在测试用例中不明显的问题是极限情况,如果你提供参数25,结果应该是cdefg而不是,不满足条件,循环永远不会被执行。

我相信你需要的是:

while ( count > 0 && *(source + count - 1) != 0 ) { /*...*/ }
                  ^^                  ^^^

AFAICT 无论如何都不需要第二个条件,因此您可以删除它并只拥有:

 while ( count > 0) { /*...*/ }

Live demo

【讨论】:

  • 演员阵容不是问题,而是问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-30
  • 1970-01-01
  • 2015-10-15
  • 2020-02-01
  • 2021-12-15
  • 2014-01-27
  • 1970-01-01
相关资源
最近更新 更多