Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为每个单词添加空格';s在C中以字符串结尾_C_Arrays_String_Pointers_Concatenation - Fatal编程技术网

为每个单词添加空格';s在C中以字符串结尾

为每个单词添加空格';s在C中以字符串结尾,c,arrays,string,pointers,concatenation,C,Arrays,String,Pointers,Concatenation,这里我有一个字符串: *line = "123 567 890 "; 末尾有两个空格。我希望将这两个空格添加到3和7的末尾,使其如下所示: "123 567 890" 我试图实现以下步骤: 按单词列表(字符串数组)将字符串解析为单词。从上游函数中,我将获得变量word_count、*line和reserve的值 在末尾用空格将它们连接起来 以从左到右的优先级分配添加空间 将所有内容连接在一起,使其成为新的*行 Word_count是*行中的字数,remaine是剩余的空格数 以下是我的

这里我有一个字符串:

*line = "123 567 890  ";
末尾有两个空格。我希望将这两个空格添加到3和7的末尾,使其如下所示:

"123  567  890"
我试图实现以下步骤:

  • 按单词列表(字符串数组)将字符串解析为单词。从上游函数中,我将获得变量word_count、*line和reserve的值
  • 在末尾用空格将它们连接起来
  • 以从左到右的优先级分配添加空间
  • 将所有内容连接在一起,使其成为新的*行
  • Word_count是*行中的字数,remaine是剩余的空格数

    以下是我的错误代码的一部分:

    int add_space(字符*行,int剩余,int单词计数)
    {
    如果(保持==0.0)
    返回0;//不需要操作。
    int ret;
    字符arr[字数][线宽];
    memset(arr,0,字数*线宽*大小(字符));
    char*blank=calloc(线宽,大小(char));
    如果(空白==NULL)
    {
    fprintf(stderr,“arr错误的calloc!\n”);
    返回-1;
    }
    for(int i=0;i

    它不工作了,你能帮我找到不工作的部件并修复它们吗?谢谢大家。

    这是一个二维字符数组

    char arr[word_count][line_width];
    
    您需要一个char*(字符指针)数组

    您分配内存的方式也不起作用

    像这样的

    for(int index=0;index<work_count;index++)
      arr[index] = malloc(line_width*sizeof(char)];
    
    for(int index=0;index[Edit]将完整代码添加到底部,并更正原始代码段

    那么,据我所知,你的愿望是取一条现有的某一长度的线,并将其重写为一条与原始线长度相同的新线,但尽可能均匀地填充空格,最后一个单词后不留空格:例如:

    “这是我的原始句子”(末尾四个空格-字符串长度为32)

    |T | h | i | s | i | s | m | y | o | r | i | g | i | n | a | l | s | e | n | T | e | n | c |

    您希望重新分配空间,以便保留原始长度32:

    |T | h | i | s | i | s | m | y | o | r | i | g | i | n | a | l | s | e | n | T | e | n | c |

    下面应该提供一组可以在代码中实现的步骤,以便在一行中均匀地分布单词,保持其原始长度

    首先,存储原始行长度:

    int origLen = strlen(line);
    
    首次使用带空格的
    strtok()
    作为分隔符分析字符串,以收集以下内容:

    1)字数
    2)所有单词的累计长度

    char *buf;
    char temp[80];    
    char lineKeep[80];
    int accumLen=0;
    int wordCount=0;
    int numSpaces;
    
    strcpy(lineKeep, line);
    
    buf = strtok(lineKeep, " ");
    while(buf)
    {
        strcpy(temp, buf);
        accumLen += strlen(temp)+1;//+1 because each word includes one following space
        wordCount++;
        buf = strtok(NULL, " ");
    }
    accumLen--; //remove last space
    
    现在您可以重复解析,但这一次您获得了在解析字符串时重新构造字符串所需的信息:

    numSpaces = (origLen - accumLen)+1;//determine number of trailing spaces after last word
                                       //+1 to compensate for space at end of last word.
    
    //parse line, place words and extra spaces  
    int spcToAdd;  //number spaces added to every word except last
    int extraSpc;  //remainder spaces to distribute  
    
    spcToAdd = numSpaces/(wordCount - 1);
    extraSpc = numSpaces%(wordCount - 1);
    
    memset(lineKeep, 0, 80);
    
    buf = strtok(line, " ");
    while(buf)
    {
        strcat(lineKeep, buf);
        for(i=0;i<spcToAdd;i++) strcat(lineKeep, " ");
        if(extraSpc > 0) strcat(lineKeep, " "), extraSpc--;
        buf = strtok(NULL, " ");
    }
    
    numSpaces=(origLen-accumLen)+1//确定最后一个单词后的尾随空格数
    //+1以补偿最后一个单词末尾的空格。
    //分析行,放置单词和额外的空格
    int spcToAdd//除了最后一个单词外,每个单词都添加了空格
    int extraSpc//要分配的剩余空间
    spcToAdd=numSpaces/(字数-1);
    extraSpc=numSpaces%(字数-1);
    memset(lineKeep,0,80);
    buf=strtok(第“”行);
    while(buf)
    {
    strcat(线路保持,buf);
    对于(i=0;i 0)strcat(线路保持“”),外部SPC--;
    buf=strtok(空,“”);
    }
    
    应该这样做

    [编辑]
    完整的代码,包括对原始代码段的更正:

    #包括
    内部主(空)
    {
    字符行[]=“这是我的原始行”;
    char*buf;
    煤焦温度[80];
    char-lineKeep[80];
    int accumLen=0;
    int wordCount=0,count;
    int numSpaces;
    int i;
    int origLen=strlen(直线);
    strcpy(lineKeep,line);
    printf(“带\“*\”的原件,用于标记空格:**%s*\n”,线条保留);
    buf=strtok(lineKeep,“”);
    while(buf)
    {
    strcpy(温度,单位温度);
    accumLen+=strlen(temp)+1;//+1,因为每个单词包含一个空格
    字数++;
    buf=strtok(空,“”);
    }
    accumLen--;//删除最后一个空格
    //第二部分
    numSpaces=(origLen-accumLen);//确定最后一个单词后的尾随空格数
    //+1以补偿最后一个单词末尾的空格。
    //分析行,放置单词和额外的空格
    int-spcToAdd;//除了最后一个之外,每个单词都添加了空格
    int extraSpc;//要分配的剩余空间
    spcToAdd=numSpaces/(wordCount-1);//添加一个额外的空间
    extraSpc=numSpaces%(wordCount-1);//当它们最后添加额外空间时
    memset(lineKeep,0,80);
    计数=0;
    buf=strtok(第“”行);
    while(buf)
    {
    计数++;
    strcat(线路保持,buf);
    if(count
    此代码的结果图像:

    [EDIT]操作带有注释的原始代码和一些编辑(未完全调试)

    int-add_空间(字符*行,int-re
    
    char *buf;
    char temp[80];    
    char lineKeep[80];
    int accumLen=0;
    int wordCount=0;
    int numSpaces;
    
    strcpy(lineKeep, line);
    
    buf = strtok(lineKeep, " ");
    while(buf)
    {
        strcpy(temp, buf);
        accumLen += strlen(temp)+1;//+1 because each word includes one following space
        wordCount++;
        buf = strtok(NULL, " ");
    }
    accumLen--; //remove last space
    
    numSpaces = (origLen - accumLen)+1;//determine number of trailing spaces after last word
                                       //+1 to compensate for space at end of last word.
    
    //parse line, place words and extra spaces  
    int spcToAdd;  //number spaces added to every word except last
    int extraSpc;  //remainder spaces to distribute  
    
    spcToAdd = numSpaces/(wordCount - 1);
    extraSpc = numSpaces%(wordCount - 1);
    
    memset(lineKeep, 0, 80);
    
    buf = strtok(line, " ");
    while(buf)
    {
        strcat(lineKeep, buf);
        for(i=0;i<spcToAdd;i++) strcat(lineKeep, " ");
        if(extraSpc > 0) strcat(lineKeep, " "), extraSpc--;
        buf = strtok(NULL, " ");
    }
    
    #include <ansi_c.h>
    int main(void)
    {
        char line[]="this is my original line      ";
        char *buf;
        char temp[80];    
        char lineKeep[80];
        int accumLen=0;
        int wordCount=0, count;
        int numSpaces;
        int i;
        int origLen = strlen(line);
    
        strcpy(lineKeep, line);
        printf("Original with \"*\" to demark spaces :*%s*\n", lineKeep);
        buf = strtok(lineKeep, " ");
        while(buf)
        {
            strcpy(temp, buf);
            accumLen += strlen(temp)+1;//+1 because each word includes one following space
            wordCount++;
            buf = strtok(NULL, " ");
        }
        accumLen--; //remove last space
    
        //second part
        numSpaces = (origLen - accumLen);//determine number of trailing spaces after last word
                                           //+1 to compensate for space at end of last word.
        //parse line, place words and extra spaces  
        int spcToAdd;  //number spaces added to every word except last
        int extraSpc;  //remainder spaces to distribute  
    
        spcToAdd = numSpaces/(wordCount - 1); //Add one extra space
        extraSpc = numSpaces%(wordCount - 1); //while they last add additional space
    
        memset(lineKeep, 0, 80);
    
        count = 0;
        buf = strtok(line, " ");
        while(buf)
        {
            count++;
            strcat(lineKeep, buf);
            if(count < wordCount)
            {
                strcat(lineKeep, " "); //normally occuring space
                for(i=0;i<spcToAdd;i++) strcat(lineKeep, " ");
                if(extraSpc > 0) strcat(lineKeep, " "), extraSpc--;
            }
            buf = strtok(NULL, " ");
        }
        lineKeep[strlen(lineKeep)]=0;
        printf("modified with \"*\" to demark spaces :*%s*\n", lineKeep);
        getchar();
        return 0;
    }
    
    int add_space(char *line, int remain, int word_count)
    {
        int line_width;  //added
    
        if (remain == 0.0)
            return 0; // Don't need to operate.
    
        line_width = strlen(line);
    
        int ret;
        char arr[word_count][line_width]; //line width not originally defined, 
        memset(arr, 0, word_count * line_width * sizeof(char));
    
        char *blank = calloc(line_width, sizeof(char));
        if (blank == NULL)
        {
            fprintf(stderr, "calloc for arr error!\n");
            return -1;
        }
    
        for (int i = 0; i < word_count; i++)
        {
            ret = sscanf(line, "%s", arr[i]); // gdb shows somehow it won't read in.
            if (ret != 1)                     // each time this loops around, "this" is placed into arr[i];
            {                                 // "line" is not changing, strtok will traverse line
                fprintf(stderr, "Error occured!\n");
                return -1;
            }
            //arr[i] = strcat(arr[i], " ");      // won't compile.
            strcpy(arr[i],strcat(arr[i], " ")); // assignment of char array to char array uses strcpy, or sprintf, et. al.
            //each loop now adds " " -> "this " 
                                                // Note: you can assign char to char using =, but not char arrays
        }
        size_t spaces = remain / (word_count * 1.0); //size_t == uint, mult by float is set back into uint.
        memset(blank, ' ', spaces + 1);
        for (int i = 0; i < word_count - 1; i++)
        {
            //arr[0] = strcat(arr[i], blank);     // won't compile.
            strcpy(arr[i],strcat(arr[i], blank)); // Same as above. and index of arr[] should be i
        }
    
        memset(blank, ' ', spaces);
        //arr[word_count-1] = strcat(arr[word_count-1], blank); //same
        strcpy(arr[word_count-1],strcat(arr[word_count-1], blank));  //at this point, each arr[i] 
                                                                     //contains "test   \0" (3 spaces and NULL)
        for (int i = 1; i < word_count; i++)
        {
            //arr[0] = strcat(arr[0], arr[i]); //same
            strcpy(arr[0], strcat(arr[0], arr[i])); 
        } //at this point arr[0] contains "test   test   test   test   t"
          //ran out of room, note there is no NULL terminator '\0' at end.
        free(blank);
        return 0;
    }
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int distributeSpaces(char* s, int wordCount, int spaceCount);
    
    int main(void) {
      char *myString = "There is a house in New Orleans       ";
      char *sCopy;
      sCopy = malloc(strlen(myString)+1);
      strcpy(sCopy, myString);
      printf("Initial string: '%s'\n", myString);
      distributeSpaces(sCopy, 7, 7);
      printf("\nString is now '%s'\n", sCopy);
      return 0;
    }
    
    int distributeSpaces(char* s, int wordCount, int spaceCount) {
      int ii, length;
      int wordLength, wordEnd;
      int spaceLeft = spaceCount + 1;
      length = strlen(s);
      printf("string is %d characters long\n", length);
      wordEnd = length - spaceLeft - 1;
      wordLength = 0;
      for(ii = length - spaceLeft - 1; ii > 0; ii--) {
        wordLength++;
        if(s[ii] == ' ') {
          // printf("found space - moving %d characters from %d to %d\n", wordLength, ii, ii+spaceLeft);
          printf("before memmove, string is '%s'\n", s);
          memmove(&s[ii+spaceLeft], &s[ii+1], wordLength);
          printf("after memmove, string is now '%s'\n", s);
          memset(&s[ii], '*', spaceLeft);
          printf("after memset, string is now '%s'\n", s);
          spaceLeft -= spaceLeft / wordCount--;
          // printf("space left is now %d\n", spaceLeft);
          wordLength = 0;
          ii--;
        }
      }
      return 0;
    }
    
    Initial string: 'There is a house in New Orleans       '
    string is 38 characters long
    before memmove, string is 'There is a house in New Orleans       '
    after memmove, string is now 'There is a house in New OrleansOrleans'
    after memset, string is now 'There is a house in New********Orleans'
    before memmove, string is 'There is a house in New********Orleans'
    after memmove, string is now 'There is a house in New***New**Orleans'
    after memset, string is now 'There is a house in*******New**Orleans'
    before memmove, string is 'There is a house in*******New**Orleans'
    after memmove, string is now 'There is a house in***in**New**Orleans'
    after memset, string is now 'There is a house******in**New**Orleans'
    before memmove, string is 'There is a house******in**New**Orleans'
    after memmove, string is now 'There is a houshouse**in**New**Orleans'
    after memset, string is now 'There is a*****house**in**New**Orleans'
    before memmove, string is 'There is a*****house**in**New**Orleans'
    after memmove, string is now 'There is a**a**house**in**New**Orleans'
    after memset, string is now 'There is****a**house**in**New**Orleans'
    before memmove, string is 'There is****a**house**in**New**Orleans'
    after memmove, string is now 'There isis**a**house**in**New**Orleans'
    after memset, string is now 'There***is**a**house**in**New**Orleans'
    
    String is now 'There***is**a**house**in**New**Orleans'