这里我有一个字符串:
*line = "123 567 890 ";
最后有2个空格。我希望将这两个空格添加到3的结尾和7的结尾,使其像这样:
"123 567 890"
我试图实现以下步骤:
Word_count是*行中的单词数,left是剩余空格数。
以下是错误代码的一部分:
int add_space(char *line, int remain, int word_count)
{
if (remain == 0.0)
return 0; // Don't need to operate.
int ret;
char arr[word_count][line_width];
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)
{
fprintf(stderr, "Error occured!\n");
return -1;
}
arr[i] = strcat(arr[i], " "); // won't compile.
}
size_t spaces = remain / (word_count * 1.0);
memset(blank, ' ', spaces + 1);
for (int i = 0; i < word_count - 1; i++)
{
arr[0] = strcat(arr[i], blank); // won't compile.
}
memset(blank, ' ', spaces);
arr[word_count-1] = strcat(arr[word_count-1], blank);
for (int i = 1; i < word_count; i++)
{
arr[0] = strcat(arr[0], arr[i]);
}
free(blank);
return 0;
}
它不起作用,你能帮我找到那些不起作用的部件吗?谢谢你们。
答案 0 :(得分:4)
这是另一种建议 - 可能更快,并且使用更少的内存。
首先 - 注意你返回的行将与你开始的行大小相同 - 所以我们只需要移动单词并添加空格。你的当前代码似乎没有尝试实际返回固定字符串,只要我能辨别......
从字符串末尾开始计算“额外空格”的数量(我认为这是你的remain
值)。现在在字符串中向后工作,直到找到最后一个单词的开头,然后移动它。
我编写了一个示例 - 使用一些调试语句使其更明显地发生了什么,并在添加空格时包括''而不是''。这更清楚地向您展示了它正在做什么(尽管您在使用此代码时希望将''替换为''。)
#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'
我认为这就是你所追求的。
答案 1 :(得分:3)
[编辑] 将完整代码添加到底部,并对原始代码段进行更正
根据我的理解,你的愿望就是取一条长度的现有线,并将其重写为与原始长度相同的新线,但填充空间尽可能均匀分布,之后没有空格最后一句话:例如:
“这是我的原始句子”(末尾有四个空格 - 字符串长度为32)
| T | H | I | S | | I | S | | M | Y | | O | R | I | G | I | N | A |升| | S | E | N | T | E | N | C ^ | E | | | | |
您希望重新分配空格,以保留原始长度32:
| T | H | I | S | | | I | S | | | M | Y | | | O | R | I | G | I | N | A |升| | | S | E | N | T | E | N | C ^ | E |
以下内容应提供一组您可以在代码中实现的步骤,以便在保持原始长度的行上均匀分布您的单词。
首先,存储原始行长度:
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, " ");
}
应该这样做。
<强> [编辑] 强>
完整代码,包含对原始代码段的更正:
#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;
}
此代码的结果图片:
[编辑] OP原始代码,包含评论和一些修改(未完全调试)
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;
}
答案 2 :(得分:0)
这是一个2 d字符数组
char arr[word_count][line_width];
你想要一个char *(字符指针)数组。
char *arr[word_count];
你分配内存的方式也不行。
像这样的东西
for(int index=0;index<work_count;index++)
arr[index] = malloc(line_width*sizeof(char)];
不要忘记在程序结束时释放,否则会有内存泄漏。