【问题标题】:Using Pointers to Modify Strings使用指针修改字符串
【发布时间】:2013-02-08 05:47:25
【问题描述】:

所以我有一个函数,它接受一个指向“字符串”数组的指针(我将字符串理解为只是后面跟着“\0”的内存块)。由于字符串已经是指向字符串第一个字节的指针,所以我的指针实际上是一个** doublePointer。但是,我对 Ying Yang 进行了分段故障,老实说,我不知道在低级别视图中发生了什么。这是我下面的代码,它的功能是读取字符并将第一个单词的首字母大写(在字符串中)和一个句点之后。

    void autocaps(char ** words)
    {

    /* Add code here */
    //Period Boolean
    bool next=false;
    //First Word Boolean
    bool fcap=true;
    //Counter Variable
    int i=0;
    int j=0;
    //Second Pointer
    char** wordx = words;

    //LowerCase Bomb & Period Flagging
    while(wordx[i][j]!='\0'){
      while(wordx[i][j]!='\0'){
       //A-Z Filter
       if((wordx[i][j]>='A')&&(wordx[i][j]<='Z')){
      wordx[i][j]+=32;
       }
       if(wordx[i][j]=='.'){
      next=true;
       }
      j++;
      }
    i++;
    }

 i=0;
 j=0;
 //Cap First Word & Cap Post Period
 while(words[i]!='\0'){
   while(words[i][j]!='\0'){
    //a-z Filter
    if((words[i][j]>=97)&&(words[i][j]<=122)){
  if(fcap){
    words[i][j]-=32;
    fcap=false;
  }
  if(next){
    words[i][j]-=32;
  }
    }
    j++;
  }
 i++;
}
return;

}

打印通过参数传递的原始指针时出现段错误。如果有人可以向我解释这个的低级概念,因为我很困惑,我到处乱扔三颗星和四颗星,我什至不知道它是否让我离调试代码更近或更远。

谢谢!!

【问题讨论】:

  • 不能说重复,但this 应该会有所帮助。
  • *wordx++ 迭代字符串,但你从不迭代字符,所以 **wordsx!='\0' 只会在你传递一个空字符串时为假,这可能不是你想要的。
  • 所有这一切都取决于您是否实际上首先将 char ** 传递给函数。如果没有这个调用的调用方,就这个问题的答案而言,它是未定义的。此外,您不会传递任何长度的序列。除非您对退出点条件使用尾空指针(我没有看到任何证据),否则这可能会很快向南。提示:如果你传入了一个 char[N][M] 变量,那么你就做错了错误。请更新问题以包含您如何调用此事物的调用方示例。

标签: c pointers segmentation-fault


【解决方案1】:

您说的是“字符串数组”,但根据您的代码和您的意图(大写第一个字符和句点之后),我将假设您打算将其用于传递给函数的单个字符串。

字符串只是一个字符数组,后面跟着一个 0 值。你想要做的是遍历字符数组。要从字符指针获取要取消引用指针的字符。这就是为什么在我们实际检查字符串中所处的字符的任何地方,您都会在下面看到“*words”。

双指针、三指针和四指针使您远离解决方案。

这是一个重新设计的示例:

void autocaps(char* words)
{
  bool fcap=true; /* true so first letter is made cap */

  while (*words != '\0') 
  {
    if (fcap)
    {
        /* capitalize */
        if ((*words >= 'a') && (*words <= 'z'))
        {
            *words -= 32;
        }

        fcap = false;
    }
    else
    {
        /* not cap */
        if ((*words >= 'A') && (*words <= 'Z'))
        {
            *words += 32;
        }
    }

    /* period - cap next letter */
    if (*words == '.')
    {
        fcap = true;
    }

    /* step to next character in array */
    words++;
  }

  return;
}

【讨论】:

  • 其实我觉得他确实打算用一个字符串指针数组。但正如@WhozCraig 所说,只要没有提供调用者代码,我们就不能肯定地说。
【解决方案2】:

我正在将字符串数组初始化为连续字符串,例如:

char *words[2] = {"hello", "world"};

那么你第一次到达时会遇到分段错误

**words+=32;

因为您正在尝试修改只读位置。

你应该像这样初始化字符串:

char word1[] = {'h', 'e', 'l', 'l', 'o', 0};
char word2[] = {'w', 'o', 'r', 'l', 'd', 0};
char *words[] = {word1, word2};

另一个问题确实是

*words++;

您不想这样做有两个原因:

  1. 正如其他海报所提到的,++ 优先于取消引用运算符,因此您实际上是将 words 数组从一个字符串递增到下一个,而不是从一个字符递增到下一个。
  2. 然后取消引用运算符没有任何影响。

现在,如果你想前进到下一个字符,你不想这样做:

(*words)++

因为现在您实际上是在更改 words 数组中的指针,而您不想这样做。

【讨论】:

  • 大家好,非常感谢您的回复,如果我让您感到困惑或没有明确说明我在做什么,我们深表歉意。我编辑了我的代码以更准确地实现我想要完成的任务。所以在初始化为 char* rolodex[25]={NULL}; 的 rolodex 上调用 autocaps它由另一个函数初始化。自动大写字母(rolodex);因此这是一个二维数组,因为它是一个指向字符串的指针数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
相关资源
最近更新 更多