[编辑]完整代码添加到底部,对原始片段进行更正
那么,据我所知,您的愿望是采用一定长度的现有行,并将其重写为与原始行长度相同的新行,但尽可能均匀地填充空格,最后一个单词后没有空格: 例如:
“This is my original sentence”(末尾四个空格 - 字符串长度为 32)
|T|h|i|s| |我|s| |m|y| |o|r|i|g|i|n|a|l| |s|e|n|t|e|n|c|e| | | | |
您想重新分配空间以保留原始长度 32:
|T|h|i|s| | |我|s| | |m|y| | |o|r|i|g|i|n|a|l| | |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;
}