[ACCEPTED]-Remove extra white space from inside a C string?-whitespace
If I may voice the "you're doing it wrong" opinion, why 8 not just eliminate the whitespace while 7 reading? Use fscanf("%s", string);
to read a "word" (non whitespace), then 6 read the whitespace. If it's spaces or tabs, keep 5 reading into one "line" of data. If it's 4 a newline, start a new entry. It's probably 3 easiest in C to get the data into a format 2 you can work with as soon as possible, rather 1 than trying to do heavy-duty text manipulation.
Why not use strtok()
directly? No need to modify 3 the input
All you need to do is repeat strtok()
until 2 you get 3 non-space tokens and then you 1 are done!
Edit: I originally had a malloced workspace, which 4 I though might be clearer. However, doing 3 it w/o extra memory is almost as simple, and I'm 2 being pushed that way in comments and personal 1 IMs, so, here comes...:-)
void squeezespaces(char* row, char separator) {
char *current = row;
int spacing = 0;
int i;
for(i=0; row[i]; ++i) {
if(row[i]==' ') {
if (!spacing) {
/* start of a run of spaces -> separator */
*current++ = separator
spacing = 1;
}
} else {
*current++ = row[i];
spacing = 0;
}
*current = 0;
}
The following code modifies the string in 4 place; if you don't want to destroy your 3 original input, you can pass a second buffer 2 to receive the modified string. Should be 1 fairly self-explanatory:
#include <stdio.h>
#include <string.h>
char *squeeze(char *str)
{
int r; /* next character to be read */
int w; /* next character to be written */
r=w=0;
while (str[r])
{
if (isspace(str[r]) || iscntrl(str[r]))
{
if (w > 0 && !isspace(str[w-1]))
str[w++] = ' ';
}
else
str[w++] = str[r];
r++;
}
str[w] = 0;
return str;
}
int main(void)
{
char test[] = "\t\nThis\nis\ta\b test.";
printf("test = %s\n", test);
printf("squeeze(test) = %s\n", squeeze(test));
return 0;
}
char* trimwhitespace(char *str_base) {
char* buffer = str_base;
while((buffer = strchr(str_base, ' '))) {
strcpy(buffer, buffer+1);
}
return str_base;
}
0
You could read a line then scan it to find 11 the start of each column. Then use the column 10 data however you'd like.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_COL 3
#define MAX_REC 512
int main (void)
{
FILE *input;
char record[MAX_REC + 1];
char *scan;
const char *recEnd;
char *columns[MAX_COL] = { 0 };
int colCnt;
input = fopen("input.txt", "r");
while (fgets(record, sizeof(record), input) != NULL)
{
memset(columns, 0, sizeof(columns)); // reset column start pointers
scan = record;
recEnd = record + strlen(record);
for (colCnt = 0; colCnt < MAX_COL; colCnt++ )
{
while (scan < recEnd && isspace(*scan)) { scan++; } // bypass whitespace
if (scan == recEnd) { break; }
columns[colCnt] = scan; // save column start
while (scan < recEnd && !isspace(*scan)) { scan++; } // bypass column word
*scan++ = '\0';
}
if (colCnt > 0)
{
printf("%s", columns[0]);
for (int i = 1; i < colCnt; i++)
{
printf("#%s", columns[i]);
}
printf("\n");
}
}
fclose(input);
}
Note, the code could 9 still use some robust-ification: check for 8 file errors w/ferror; ensure eof was hit 7 w/feof; ensure entire record (all column 6 data) was processed. It could also be made 5 more flexible by using a linked list instead 4 of a fixed array and could be modified to 3 not assume each column only contains a single 2 word (as long as the columns are delimited 1 by a specific character).
Here's an alternative function that squeezes 2 out repeated space characters, as defined 1 by isspace()
in <ctype.h>
. It returns the length of the 'squidged' string.
#include <ctype.h>
size_t squidge(char *str)
{
char *dst = str;
char *src = str;
char c;
while ((c = *src++) != '\0')
{
if (isspace(c))
{
*dst++ = ' ';
while ((c = *src++) != '\0' && isspace(c))
;
if (c == '\0')
break;
}
*dst++ = c;
}
*dst = '\0';
return(dst - str);
}
#include <stdio.h>
#include <string.h>
int main(void)
{
char buffer[256];
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
size_t len = strlen(buffer);
if (len > 0)
buffer[--len] = '\0';
printf("Before: %zd <<%s>>\n", len, buffer);
len = squidge(buffer);
printf("After: %zd <<%s>>\n", len, buffer);
}
return(0);
}
I made a small improvment over John Bode's 1 to remove trailing whitespace as well:
#include <ctype.h>
char *squeeze(char *str)
{
char* r; /* next character to be read */
char* w; /* next character to be written */
char c;
int sp, sp_old = 0;
r=w=str;
do {
c=*r;
sp = isspace(c);
if (!sp) {
if (sp_old && c) {
// don't add a space at end of string
*w++ = ' ';
}
*w++ = c;
}
if (str < w) {
// don't add space at start of line
sp_old = sp;
}
r++;
}
while (c);
return str;
}
#include <stdio.h>
int main(void)
{
char test[] = "\t\nThis\nis\ta\f test.\n\t\n";
//printf("test = %s\n", test);
printf("squeeze(test) = '%s'\n", squeeze(test));
return 0;
}
br.
The following code simply takes input character 6 wise, then check for each character if there 5 is space more than once it skips it else 4 it prints the character. Same logic you 3 can use for tab also. Hope it helps in solving 2 your problem. If there is any problem with 1 this code please let me know.
int c, count = 0;
printf ("Please enter your sentence\n");
while ( ( c = getchar() ) != EOF ) {
if ( c != ' ' ) {
putchar ( c );
count = 0;
}
else {
count ++;
if ( count > 1 )
; /* Empty if body */
else
putchar ( c );
}
}
}
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.