C语言 为什么for循环给予输出?

ix0qys7i  于 2023-03-01  发布在  其他
关注(0)|答案(2)|浏览(172)

问题是当我给予一个代码时,它并不显示任何输出,它只是挂起。我只是不明白为什么代码不工作。是C语言的局限性还是代码有什么问题?到底是什么导致了这个问题?
对于以下输入:

2
http:\\lightoj.com

该程序用于输出:

https:\\lightoj.com

但它什么也没做,我认为问题是在for循环中声明多个变量,因为如果我不在else内部的循环中使用多个变量(而不是for(int j = 0, k = 0; j < l; j++, k++),使用for(int j = 0; j < l; j++)),那么代码会显示输出(当然不是预期的输出)。

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

int main()
{
    int T, n;
    scanf("%d", &T); // Test Case

    for (int i = 0; i < T; i++) // Test case loop
    {
        char *s;
        scanf("%s", s); // taking a string

        if (s[4] == 's') // if the text has (https:\\lightoj.com) 's' in 4th index then it will //print the string as it is
        {
            printf("Case %d: %s\n", i+1, s);
        }
        else
        {
            printf("Case %d: ", i + 1);

            int l = strlen(s);

            for (int j = 0, k = 0; j < l; j++, k++)
            {
                if (k == 4)
                {
                    printf("s"); // In the forth index printing s
                    j--; // changing j = 4 to j = 3
                }
                else
                {
                    // printf("i = %d j = %d\n", i, j);
                    printf("%c", s[j]); 
                    // printing each character of (http:\\lightoj.com) to (https:\\lightoj.com)
                }        
            }
            printf("\n");
        }
    }
}

我确实尝试了很多方法来找出问题的确切位置。所以我首先检查多变量循环是否有任何问题。结果它工作了。没有测试用例循环。如下所示
1)单独检查

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

int main()
{   
   //without the test case loop the program works fine. It gives proper output
    int i = 0; 
    char *s;
    scanf("%s", s);

    if (s[4] == 's') {
        printf("%s\n", s);
    }
    else
    {
        printf("Case %d: ", i + 1);

        int l = strlen(s);
        for (int j = 0, k = 0; j < l; j++, k++)
        {
            if (k == 4)
            {
                printf("s");
                j--;
            }
            else
            {
                // printf("i = %d j = %d\n", i, j);
                printf("%c", s[j]);
            }        
        }
        printf("\n");
    }    
}

1.但是如果我在另一个循环(测试用例循环)中尝试相同的代码,那么它不会显示输出。

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

int main()
{
    int T, n;
    scanf("%d", &T);

    for (int i = 0; i < T; i++)
    {
        char *s;        
        scanf("%s", s);

        if (s[4] == 's')
        {
            printf("Case %d: %s\n", i+1, s);
        }
        else
        {
            printf("Case %d: ", i + 1);

            int l = strlen(s);

            for (int j = 0, k = 0; j < l; j++, k++)
            {
                if (k == 4)
                {
                    printf("s");
                    j--;
                }
                else
                {
                    // printf("i = %d j = %d\n", i, j);
                    printf("%c", s[j]);
                }        
            }
            printf("\n");
        }
    }
}

1.在测试用例循环中,如果我将for(int j = 0, k = 0; j < l; j++, k++)更改为for(int j = 0; j < l; j++),它会工作,但我无法使用我的逻辑来解决问题。

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

int main()
{
    int T, n;
    scanf("%d", &T);

    for (int i = 0; i < T; i++)
    {
        char *s;        
        scanf("%s", s);

        if (s[4] == 's')
        {
            printf("Case %d: %s\n", i+1, s);
        }
        else
        {
            printf("Case %d: ", i + 1);

            int l = strlen(s);

            for (int j = 0; j < l; j++)
            {
                if (j == 4)
                {
                    printf("s");
                    // j--;
                }
                else 
                {
                    // printf("i = %d j = %d\n", i, j);
                    printf("%c", s[j]);
                }        
            }
            printf("\n");
        }
    }
}
goucqfw6

goucqfw61#

至少这些问题:

未初始化的指针

代码将缺少指定值的s传递给scanf()。因此,结果是 * 未定义的行为 *(UB)。

// Bad
char *s;
scanf("%s", s); // taking a string

相反,使用一个大数组、一个 width 限制并检查返回值。

char s[100 + 1];  // A location to store a string up to length 100.
if (scanf("%100s", s)  != 1) {
  fprintf(stderr, "Trouble reading.\n");
  return -1;
}

一个更好的选择是使用fgets()-尽管在前面的scanf("%d", &T);之后会有问题。最好在整个过程中使用fgets()

char s[100 + 1];  // A location to store a string up to length 100.
if (fgets(s, sizeof s, stdin) == NULL) {
  fprintf(stderr, "Trouble reading.\n");
  return -1;
}
// Note that at this point, s likely contains a '\n`.

测试垃圾

除非s中的 string 足够长,否则应尝试使用if (s[4] == 's')

nhaq1z21

nhaq1z212#

问题是你的代码有未定义的行为:为%s转换说明符传递一个指向scanf()的未初始化指针:

char *s;
    scanf("%s", s); // taking a string

未定义的行为意味着任何事情都可能发生。正如你所观察到的,你的程序可能会停止,并伴随或不伴随错误信息。
您应该将s定义为数组,指定要存储到数组中的最大字符数,并测试输入失败:

char s[100];
    if (scanf("%99s", s) != 1) {
        printf("missing input\n");
        return 1;
    }

还请注意,可以使用测试和printf语句解决此问题。
以下是修改后的版本:

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

int main(void) {
    int T;

    // read the number of test cases
    if (scanf("%d", &T) != 1) {
        fprintf(stderr, "missing number of test cases\n");
        return 1;
    }
    for (int i = 0; i < T; i++) {
        char s[100];
        if (scanf("%99s", s) != 1) {
            fprintf(stderr, "missing input\n");
            return 1;
        }
        if (strlen(s) <= 4 || s[4] == 's') {
            // no change needed
            printf("%s\n", s);
        } else {
            // insert an `s` before the fifth character
            printf("%.4ss%s\n", s, s + 4);
        }
    }
    return 0;
}

相关问题