【问题标题】:So if I scanf("%c",del), before reading the string, it works, but after it doesn't因此,如果我 scanf("%c",del),在读取字符串之前,它可以工作,但之后就不行了
【发布时间】:2018-05-02 21:06:33
【问题描述】:

所以我做了一个从字符串中删除字符的程序,它看起来像这样:

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

char* deleteChar(char* texto,int n,char del,int i,int j)
{
    /*for(i=0,j=0;i<n;i++)
        if(texto[i]!=del)
        {
            texto[j]=texto=i;
            j=+1;
        }
        for(n-i;n-i<n;i--)
            texto[n-i]=NULL;
        return(texto);*/

    if(i!=n)
    {
        if(texto[i]!=del)
        {
            texto[j]=texto[i];
            j+=1;
        }
        i+=1;
        texto=deleteChar(texto,n,del,i,j);
    }
    else
    {
        i=i-j;
        for(n-i;n-i<n;i--)
            texto[n-i]=NULL;
        return(texto);
    }
}

void main()
{
    char del;
    printf("Remover: \n");
    scanf("%c",&del);

    char* texto;
    texto=(char*)calloc(0,sizeof(char));
    printf("Texto: \n");
    scanf("%s",texto);
    int n=0;
    n=strlen(texto);

    /*char del;
    scanf("%c",&del);*/

    texto=deleteChar(texto,n,del,0,0);
    printf("%s ",texto);
}

关注main(),由于某种原因,如果我在得到我的字符串后scanf("%c",&amp;del),程序会中断(甚至在得到del 输入之前),但如果我在它工作得很好之后再这样做。 我不知道为什么。

【问题讨论】:

  • calloc(0,sizeof(char)); 没有给你足够的空间来使用scanf("%s", texto)
  • 如果你把scanf("%c",&amp;del)放在字符串输入之后,它会占用输入缓冲区中剩余的换行符。在%c 之前放置一个空格,就像scanf(" %c",&amp;del) 一样,因为与大多数格式说明符不同,%c 不会自动跳过前一个输入中剩余的空格。这是最常见的 C 问题之一。
  • 使用好名字而不是 i,j。此外,没有理由将 0,0 作为初始值传递,它们应该在例程中声明和初始化。

标签: c string scanf


【解决方案1】:

问题是你在行中重新声明了del

char del;
scanf("%c",&del);

所以只需删除del 的第二次减速。

【讨论】:

    【解决方案2】:

    您只为一个char分配空间

    texto = (char*)calloc(0, sizeof(char));
    

    您需要为整个字符串分配足够的空间,包括 NULL 终止符,这将让您拥有一个 20 个字符加上一个 NULL 终止符的字符串

    texto = (char*)calloc(21,  sizeof(char));
    

    而且您至少应该控制在scanf() 中可以读入字符串的字符数,这样就不会溢出缓冲区

    scanf("%20s", texto);
    

    为了更安全和更强大的用户输入,您应该查找fgets()

    【讨论】:

      【解决方案3】:

      在读取字符串后,您在读取 ​​del 时遇到问题,因为用于读取字符串的 scanf() 在输入缓冲区中留下未使用的最终 \n,如果您的格式字符串是这样的

      scanf("%s", stringname);
      scanf("%c", charactername);
      

      你可以解决这个问题

      scanf("%s", stringname);
      scanf(" %c", charactername);
      

      在用于读取字符的scanf() 中的%c 之前添加一个空格。这将在读取实际字符之前消耗输入缓冲区中仍保留的任何空白字符。

      这是因为 %c 的前导空白不会自动跳过。

      请注意,您只为单个字符分配内存

      char* texto;
      texto=(char*)calloc(0,sizeof(char));
      

      你可以这样做

      char* texto;
      texto=calloc(0,sizeof(char)*10);
      

      其中10 是包含\0 字符的字符串的大小。所以texto最多可以读9个字符,否则会溢出。

      为避免溢出,在使用scanf() 读取时,请使用宽度说明符,如

      scanf("%9s", texto);
      

      您无需在 C 中显式转换 calloc() 的返回值。将隐式完成从 void * 返回的 char * 的转换 calloc()

      而删除你可以这样做

      char* deleteChar(char* texto,int n,char del,int i,int j)
      {
          char *ptr=strchr(texto, del);
          if(ptr!=NULL)
          {
              sprintf(texto, "%.*s%s", ptr-texto, ptr+1);
          }   
      }
      

      您不需要返回texto,因为传递的是一个数组。

      char* deleteChar(char* texto,int n,char del,int i,int j)
      {
          char *ptr=strchr(texto, del);
          if(ptr!=NULL)
          {
              sprintf(texto, "%.*s%s", ptr-texto, texto, ptr+1);
          }   
      }
      

      strchr() 用于获取字符串中字符的第一次出现。

      另外,main() 的返回类型不应该是void。见Return type of main function

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-10
        • 2023-03-07
        • 2015-12-11
        • 1970-01-01
        • 2012-01-14
        • 1970-01-01
        • 2023-01-17
        • 1970-01-01
        相关资源
        最近更新 更多