【问题标题】:Confusion C begining混乱C开头
【发布时间】:2016-10-04 14:03:16
【问题描述】:
#include <stdio.h>
#include <string.h>


int main()
{
 char a[250];
 char c1[1],c2[1];
int n,i;


printf("Give text: ");
gets(a);

printf("Give c1: ");
gets(c1);
  printf("Give c2: ");
 gets(c2);

n=strlen(a);

for(i=0;i<n;i++)
{
    if(a[i]==c1)
 {
      a[i]=c2;
   }
  if(a[i]==c2)
 {
    a[i]=c1;
   }
   }
     printf("%s",a);
return 0;
}

在文本中,我需要将c1c2 切换并反转, 但是当我在给出c1c2 之后启动程序时,什么也没发生。 我哪里错了?

【问题讨论】:

  • 你不应该使用gets(),它有不可避免的缓冲区溢出风险,在C99中已弃用并从C11中删除。
  • gets(c1);char c1[1] 不好,因为它只接受零个字符 + 终止空字符。 a[i]=c2;a[i]=c1; 看起来很奇怪,因为它正在分配从数组转换的指针转换的内容。
  • 您想了解 C-"string" 是如何实现的。定义为 char c[1] 的 C-“字符串”只能包含“emtpy 字符串”:""
  • 请正确缩进您的代码,至少在将其呈现给全世界阅读之前... :-(
  • 我的意思是'char c1[1],c2[1]; ???你是另一种生活中的小气会计吗?用 bean-counting 敲击,除此之外,[1] 无论如何都是愚蠢的,正如其他人指出的那样:(

标签: c arrays char fgets


【解决方案1】:

首先,don't use gets(), it's inherently dangerous,改用fgets()

最重要的是,当您使用gets(c1)c1 作为单元素数组时,您已经超出了调用undefined behavior 的分配内存。

也就是说,您有 c1c2 作为单元素数组,它们没有错,但也不需要。将它们定义为简单的char 变量

char c1;
char c2;

并像使用它们

 scanf(" %c", &c1);  // mind the space and don't forget to to check the return 
 scanf(" %c", &c2);  // value of scanf() to ensure proper scanning.

之后,a[i] == c2 的检查应该是 else 构造,否则,您将覆盖之前的操作。类似的东西

for(i=0;i<n;i++)
{
    if(a[i]==c1)
   {
      a[i]=c2;
   }
  else if(a[i]==c2)
   {
    a[i]=c1;
   }
}

【讨论】:

  • 目前&amp;c1 的计算结果为char**"%c" 需要 char*
  • @alk erm...我不是已经提到define them as simple char variables and use them like了吗? :)
  • 确实,你做到了。请原谅...:}
【解决方案2】:
  • gets() 不应使用,因为它具有不可避免的缓冲区溢出风险,在 C99 中已弃用,并已从 C11 中删除。
  • c1c2 的缓冲区大小不足。
  • 您应该检查读数是否成功。
  • 在比较检索读取的字符之前,您应该取消引用 c1c2
  • 请使用else if,否则修改后的字符会被再次修改。

试试这个:

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

/* this is a simple implementation and the buffer for \n is wasted */
char* safer_gets(char* buf, size_t size){
  char* lf;
  if (fgets(buf, size, stdin) == NULL) return NULL;
  if ((lf = strchr(buf, '\n')) != NULL) *lf = '\0';
  return buf;
}

int main()
{
  char a[250];
  char c1[4],c2[4]; /* need at least 3 elements due to the inefficient implementation of safer_gets */
  int n,i;


  printf("Give text: ");
  if(safer_gets(a, sizeof(a)) == NULL)
  {
    fputs("read a error\n", stderr);
    return 1;
  }

  printf("Give c1: ");
  if(safer_gets(c1, sizeof(c1)) == NULL)
  {
    fputs("read c1 error\n", stderr);
    return 1;
  }
  printf("Give c2: ");
  if(safer_gets(c2, sizeof(c2)) == NULL)
  {
    fputs("read c2 error\n", stderr);
    return 1;
  }

  n=strlen(a);

  for(i=0;i<n;i++)
  {
    if(a[i]==*c1)
    {
      a[i]=*c2;
    }
    else if(a[i]==*c2)
    {
      a[i]=*c1;
    }
  }
  printf("%s",a);
  return 0;
}

【讨论】:

  • 为什么是c[4]?一个用于char,一个用于\n,一个用于0-终止符给出3。:-S 第4个是著名的Angst-Byte吗? ;-)
  • 嗯,我怀疑看到*c1 是否比找到c[0] 更容易理解...
猜你喜欢
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 2023-04-03
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
  • 2019-08-25
相关资源
最近更新 更多