char *r, *w;
for (w = r = str; *r; r++) {
if (*r != ',') {
*w++ = *r;
}
}
*w = '\0';
Answer from melpomene on Stack Overflowchar *r, *w;
for (w = r = str; *r; r++) {
if (*r != ',') {
*w++ = *r;
}
}
*w = '\0';
Create a new string with the same size (+1 for the terminating character) as your current string, copy each character one by one and replace ',' by ' '.
In a for loop you would have something like this :
if (old_string[i] == ',')
new_string[i] = ' ';
else
new_string[i] = old_string[i];
i++;
Then after the for loop, do not forget to add '\0' at the end of new_string.
strip commas from string
Remove spaces and commas at the end and beginning of comma separated string
Remove spaces and remove a value
Remove spaces before commas in string
Let the standard library do the work for you:
#include <algorithm>
str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
If you don't want to modify the original string, that's easy too:
std::string str2(str1.size(), '0');
str2.erase(std::remove_copy(str1.begin(), str1.end(), str2.begin(), ','), str2.end());
You need to do a resize instead at the end.
Contrary to popular belief an std::string CAN contain binary data including 0s. An std::string 's .size() is not related to the string containing a NULL termination.
std::string s("\0\0", 2);
assert(s.size() == 2);
You are making the problem more difficult than it needs to be. strtok takes multiple delimiters provided in a string and will consider a sequence of any combination of the delimiters as a single delimiter. So to handle parsing your .csv file where there may or may not be spaces surrounding the comma, simply include " ,\n" (space, comma, newline) as your delimiters and then strtok will split each token removing the comma as well as any leading spaces or trailing newline.
That reduces your code to simply:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
#define DELIM " ,\n"
int main (void) {
char buf[MAXC]; /* buffer to hold each line */
while (fgets (buf, MAXC, stdin)) { /* read each line */
char *p = buf; /* pointer to line */
/* now simply use strtok to separate all tokens in line */
for (p = strtok(p, DELIM); p; p = strtok (NULL, DELIM))
printf ("%-8s", p); /* output as desired */
putchar ('\n'); /* tidy up with newline */
}
return 0;
}
Example Use/Output
$ ./bin/strtokcsv <dat/spacecomma.csv
10 bob 18 3.5
15 mary 20 4.0
5 tom 17 3.8
(you can adjust the output format as desired).
Also see the comment by @Kaz. A simple loop with getchar() reading a character-at-a-time in a state loop, where you loop checking characters outputting things that are not spaces, commas or newlines, and when you hit a space or comma simply insert an output separator of your choosing and ignore all subsequent spaces, commas, etc.. until you reach your next field and start outputting characters again. Definitely worth looking at. Let me know if you have further question.
Assuming the CSV data doesn't contain quotes that protect commas, we can remove the extra spaces around commas using a program that doesn't do any buffering of the data or any sort of processing with null-terminated character arrays. We just read one character at a time using getchar, and maintain some state in the form of counters that measure how many spaces and commas we have seen:
#include <stdio.h>
int main(void)
{
int nspc = 0;
int ncomma = 0;
int ch;
while ((ch = getchar()) != EOF) {
switch (ch) {
case ' ': nspc++; break;
case ',': ncomma++; break;
default:
if (ncomma > 0)
while (ncomma-- > 0)
putchar(',');
else
while (nspc-- > 0)
putchar(' ');
putchar(ch);
nspc = 0;
ncomma = 0;
break;
}
}
return 0;
}
Test data:
$ cat clean-comma-test
a
aa
a,
,a
a a,
,a a
a , b
, a , b c , d
, a , b c d ef, g h
,
,a
, ,
, ,, , , ,
Output:
a
aa
a,
,a
a a,
,a a
a,b
,a,b c,d
,a,b c d ef,g h
,
,a
,,
,,,,,,
The basic idea is:
if we see a field of N spaces that doesn't contain any commas, followed by a character C which isn't a space or comma, then we just reproduce N spaces and character C.
if we see a field of N spaces (possibly 0) containing one or more commas M, followed by a character C that isn't a space or comma, we reproduce the M commas, followed by C.
lines in C streams are terminated by the newline character
'\n', which serves as C in the case when the comma-space field is the last item in the line.
A C program that doesn't manipulate any pointers cannot have a buffer overflow or memory leak. However, I haven't protected the counters against integer overflow. If you have a field of more than INT_MAX spaces and/or commas, the behavior is undefined. On modern systems, that's well over two billion, so there is a fair amount of justification for not caring about it.
The code also doesn't recognize other whitespace such as tabs.
I need to read a .txt file using an ifstream and replace all commas with spaces.
i think this can be done by regEx by i don't how to look it up.
this is a learning project, but i am just thinking about the scale
i have a form where the user enter a bunch of categories and i want the user to separate those categories with a comma, but working on the case where the user add the comma but also a space after the comma (as we all do) or before the comma, how to go about treating this case, because i don't want to end up with two or three categories that are the same.
edit: i did it but i don't want to remove the post to help anyone with the same issue.
here's what i did
const categoriesAsString = e.target.value;
const categoriesTrimmed = categoriesAsString.trim();
const categoriesAsStringWithWhiteSpace = categoriesTrimmed.replace(/\s*,\s*/g,",");
const categoriesAsArray = categoriesAsStringWithWhiteSpace.split(",");
setCategories(categoriesAsArray);