【问题标题】:Trying to fix - segmentation fault in C尝试修复 - C 中的分段错误
【发布时间】:2020-05-11 16:58:57
【问题描述】:

我正在执行一个方法,用“%20”替换字符串中的所有空格。可以假设字符串末尾有足够的空间来容纳额外的字符,并且给定了字符串的“真实”长度。

示例:

输入:“约翰·史密斯先生”,13

输出:“Mr%20John%20Smith”

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

void URL(char str[], int length)
{

    int spacecount = 0, index;

    for (int i = 0; i < length; i++)
    {
        if (str[i] == ' ')
        {
            spacecount++;
        }
    }
    index = length + spacecount * 2;
    if (length < strlen(str))
        str[length] = '\0';

    for (int j = length - 1; j >= 0; j--)
    {
        if (str[j] == ' ')
        {
            str[index - 1] = '0';
            str[index - 2] = '2';
            str[index - 3] = '%';
            index = index - 3;
        }
        else
        {
            str[index - 1] = str[j];
            index--;
        }
    }
    printf("%s", str);
}

int main()
{
    char str[100];
    int len;
    printf("Enter the string : ");
    scanf("%s", str);
    printf("Enter the length : ");
    scanf("%d", &len);
    URL(str, len);
}

在使用 gcc 编译器执行上述代码时,我遇到了分段错误。我明白了,什么是分段错误。我想在这个程序中修复它。

【问题讨论】:

  • for (int j = length - 1; j &gt;= 0; j++) 这会永远存在,你不是说j-- 吗?
  • 我假设段错误发生在这里:str[length] = '\0',你需要分配一个新的块:char newstr[index + 1],然后使用newstr而不是str
  • 我需要就地解决这个操作
  • 你使用调试器并逐行执行吗?
  • 没有机会就地替换空格,原始长度不够大,在java或pyhon之类的语言中你会得到IndexOutOfBoundException(或类似的),C不控制它,但是它并不意味着你可以毫无后果地走出阵列

标签: c segmentation-fault


【解决方案1】:

怎么样

scanf("%s", str);

工作?

如果您的输入是:Mr John Smithstr 将包含什么

它没有按照你的想法做!答案是它将包含Mr,因此您没有长度为 13 的字符串。

请改用fgets,但记得删除换行符。

完整的程序可能是:

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

void URL(char str[], int length)
{
    printf("input: |%s|\n", str);
    int spacecount = 0, index;

    for (int i = 0; i < length; i++)
    {
        if (str[i] == ' ')
        {
            spacecount++;
        }
    }
    index = length + spacecount * 2;
    str[index] = '\0';
    for (int j = length - 1; j >= 0; j--)
    {
        if (str[j] == ' ')
        {
            str[index - 1] = '0';
            str[index - 2] = '2';
            str[index - 3] = '%';
            index = index - 3;
        }
        else
        {
            str[index - 1] = str[j];
            index--;
        }
    }
    printf("output: |%s|\n", str);
}

int main()
{
    char str[100];
    int len;
    printf("Enter the string : ");
    fgets(str, 100, stdin);
    len = strlen(str);
    if (len > 0 && str[len-1] == '\n') str[--len] = '\0';
    URL(str, len);
}

输入:

Mr John Smith     

注意:Smith 后面多了 5 个空格

输出:

input: |Mr John Smith     |
output: |Mr%20John%20Smith%20%20%20%20%20|

【讨论】:

  • 在解决方案中,您假设 len 是由用户计算的,但长度的输入是由用户给出的。输入:|Mr John Smith |,13 输出:|Mr%20John%20Smith|。这里我在输入“Smith”后添加了额外的四个空格,这使得字符串的实际计数为 17。
  • 另外,如果使用fgets(str, 100, stdin) 编辑程序,输出为“This%20is%20JohnS”。
  • @Madhumitha 如果您更喜欢将长度作为用户输入,它不会有太大变化 - 只要输入正确
  • 我同意。无论如何,它有效。感谢 fgets() 的建议。
【解决方案2】:

除了使用fgets,如@4386427 所建议的那样,您还可以使用scanf 和说明符%[^\n](匹配任何不是\n)来读取整行,如下所示:

scanf(" %[^\n]", str);

为了安全起见,在处理字符串时,您应该始终限制可以读取的字符数,使其不超过数组str 的长度,方法是:

scanf(" %99[^\n]", str);

所以你的main 可能是:

int main()
{
    char str[100];
    int len;
    printf("Enter the string : ");
    scanf(" %99[^\n]", str);
    for (int c=getchar(); c!='\n' && c!=EOF; c=getchar());
    len = strlen(str);
    URL(str, len);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-31
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 2017-02-14
    • 2021-07-18
    相关资源
    最近更新 更多