首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C使用字符串和SEGFAULT

C使用字符串和SEGFAULT
EN

Stack Overflow用户
提问于 2013-12-04 08:34:46
回答 2查看 91关注 0票数 0

你好,为我糟糕的英语感到抱歉。

我从C语言开始,但我没有得到很好的指针……

我搜索了相似的主题,但我没有从他们那里得到,所以我创建了自己的主题。

我得到了主函数,在那里我调用了函数newSpeak。

这是我的newSpeak代码,但并不是万能的……

代码语言:javascript
复制
char * newSpeak ( const char * text, const char * (*replace)[2] )
{
int i;
char * alpha;
for(i=0;i<4;i++)
    {
        alpha=strstr(text, replace[0][4]);
        if(alpha[0])
            strncpy (alpha,replace[1][0],10);   
    }
return 0;

}

感谢您的回复编辑:我找到了问题的根源。当我不使用循环并运行一次时,它起作用了。但即使for cycle中的条件是i<1,它也不能工作,这应该会使它只运行once...This对我来说很奇怪……

EN

回答 2

Stack Overflow用户

发布于 2013-12-04 08:47:55

这条线

代码语言:javascript
复制
 strncpy (alpha,replace[1][0],10);   

应该已经生成了编译器警告(并且永远不要忽略编译器警告)。函数原型是

代码语言:javascript
复制
char *strncpy( char *dest, char *source, int n);

但是您正在向它传递replace[1][0],这是一个字符。如果你通过了,它可能会起作用

代码语言:javascript
复制
strncpy( alpha, &replace[1][0], 10);

即使到那时,我仍然很担心。可能是因为alpha指向的是text所指向的块中的一个内存块,这是一个const char*,所以不允许修改该内存。

我想我的第一点是错的--我读错了你的原型。但我非常确定第二点是有效的(这可能就是segfault的原因)。

second edit可能是text分配的内存不足,无法将10个字符从replace复制到其中。意识到你正在匹配的东西(replace[0][4])和你正在复制的东西(replace[1][0]])不是一回事;而且,你在i上循环,但没有使用那个值……这让我想知道是否有拼写错误(我不是透视者,不知道你想从一个循环到另一个循环改变什么)。

您需要检查要复制到的对象的大小:

代码语言:javascript
复制
strncpy(alpha, replace[1][0], (strlen(alpha)<10)?strlen(alpha):10);

将确保您复制的字符不超过10个,并且不超过alpha中的空格。

这是在已经指出的所有其他内容的基础上(其中使用if (alpha!=NULL)而不是if(alpha[0])是一个很大的问题)。

EDIT 3 -我想我现在已经解决了你代码中的大部分问题了……关于一个小的“工作”示例,请参见http://codepad.org/YK5VyGAn

您的代码存在以下问题:

  1. 你声明textconst char*,然后继续修改它
  2. 你声明replaceconst char* (*replace)[2],然后地址元素replace[0][4] (4 >2...)
  3. 你将strstr的返回值赋给alpha;这可能是NULL (不匹配),但是您测试alpha[0] (如果您复制了替换字符串,您复制了“最多10个字符”,则测试将失败-无论(a)目标字符串是否可以容纳此字符,以及(b)源字符串是否具有如此多的字符。结果可能是您复制了完整的源字符串(包括结尾'\0'),这样之后就不会再找到另一个匹配项(您已经“删除”了字符串的其余部分)。然后你会遇到"strstr returns“错误...

我不确定(没有看到你的输入字符串或“替换”字符串)是哪一个真正导致了你的代码失败--我已经写了一个小程序来解决所有这些错误。你可以在http://codepad.org/4jSOnmPy上找到它-在这里转载:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MIN(a,b) (a>b)?(b):(a)

char * newSpeak (const char *text, const char *(*replace)[5] ){
  int ii=0, n;
  char *alpha, *beta;
  printf("length of input string is %d\n", strlen(text));
  beta = malloc(strlen(text)+1);
  printf("allocated %d bytes\n", strlen(text)+1);
  fflush(stdout);
  strcpy(beta, text);
  printf("copy OK: beta now %s\n", beta);
  fflush(stdout);
  for(ii = 0; ii < 4; ii++) {
//    alpha=strstr(beta, replace[0][0]);
    alpha=strstr(beta, "a");
    printf("alpha is '%s'\n", alpha);
    fflush(stdout);
    if(alpha!=NULL) {
      char *rs;
      rs = replace[1][ii];
      printf("ii = %d; alpha now: '%s'\n", ii, alpha);
      fflush(stdout);
      n = MIN(strlen(alpha), strlen(rs));
      printf("n is now %d\n", n);
      fflush(stdout);
      printf("going to copy at most %d characters from '%s' into '%s'\n", n, rs, alpha);
      fflush(stdout);
      strncpy (alpha,rs,n);  
      printf("beta is now '%s'\n", beta);
      fflush(stdin); 
    }
    else printf("no match found\n");
  }
  return beta;
}

int main(void) {
  char* r[2][5]={{"a","b","c","d", "e"}, {"o","e","i","u","s"}};
  char* myText = "this is a vary sally strang";
  printf("NewSpeak: %s\n", "hello world");
  printf("converted: %s\n", newSpeak(myText, r));
  return 0;
}

输出:

代码语言:javascript
复制
NewSpeak: hello world
length of input string is 27
allocated 28 bytes
copy OK: beta now this is a vary sally strang
alpha is 'a vary sally strang'
ii = 0; alpha now: 'a vary sally strang'
n is now 1
going to copy at most 1 characters from 'o' into 'a vary sally strang'
beta is now 'this is o vary sally strang'
alpha is 'ary sally strang'
ii = 1; alpha now: 'ary sally strang'
n is now 1
going to copy at most 1 characters from 'e' into 'ary sally strang'
beta is now 'this is o very sally strang'
alpha is 'ally strang'
ii = 2; alpha now: 'ally strang'
n is now 1
going to copy at most 1 characters from 'i' into 'ally strang'
beta is now 'this is o very silly strang'
alpha is 'ang'
ii = 3; alpha now: 'ang'
n is now 1
going to copy at most 1 characters from 'u' into 'ang'
beta is now 'this is o very silly strung'
converted: this is o very silly strung

注意--我添加了很多“无用”的输出,包括fflush(stdout);语句。这是一种很好的方法,可以确保调试打印输出可以准确地显示出程序运行到什么程度,以及在程序崩溃之前发生了什么--如果没有fflush,您可能会丢失许多行输出(因为它们从未“出现在屏幕上”)。

从上面可以明显看出,如果您的替换字符串的长度与它们替换的字符串长度不同,您将得到一些奇怪的覆盖(我将搜索和替换字符串长度都保留为1,但没有理由这样做)。

我希望这能帮到你!

票数 2
EN

Stack Overflow用户

发布于 2013-12-04 08:51:02

代码语言:javascript
复制
    alpha=strstr(text, replace[0][4]);
    if(alpha[0])
        // looks crashy

man strstr:

这些函数返回指向子字符串开头的指针,如果找不到子字符串,则返回NULL。

编辑:

很难知道你在尝试做什么,但在下面找到你的代码的任意改编。如果是我的程序,我会写出非常不同的代码。我之所以提到这一点,是因为我不希望有人读到这篇文章,认为这是应该做的事情。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

void newSpeak (char *text, const char *replace[4][2])
{
  int i, j;
  char *alpha;
  for (i = 0; i < 4; i++) {
    if (alpha = strstr(text, replace[i][0])) {
      for (j = 0; alpha[j] && replace[i][1][j]; j++)
        alpha[j] = replace[i][1][j];
    }
  }
}

int main ()
{
  char buf[100] = "abc";
  const char *replace[4][2] = {
    { "a", "e" },
    { "b", "f" },
    { "c", "g" },
    { "d", "h" },
  }; 
  newSpeak(buf, replace);
  puts(buf);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20364584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档