Right now I have a string looking like this:
A sentence
with a newline.
I'm reading the string in via console input like so:
ch = getchar();
while (ch != '.') {
msg[i] = ch;
i++;
ch = getchar();
}
And, after reading it in, I remove the whitespace present by doing this in a function and applying to the msg char array:
char *remove_white_spaces(char *str) {
int i = 0, j = 0;
while (str[i]) {
if (str[i] != ' ')
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
I've tried looping over it and stopping at \n but that leaves an output of "Asentence", as the string terminates as the \n is set to 0.
Whole main:
int main(void) {
char msg[MAX_MSG_LEN+1];
char ch;
int i = 0;
ch = getchar();
while (ch != '.') {
msg[i] = ch;
i++;
ch = getchar();
}
msg[i] = '.';
msg[i + 1] = '\0';
remove_white_spaces(msg);
printf("%s\n", msg);
return 0;
}
You can use the isspace function to test for and skip any/all whitespace characters, include the normal space and the newline character(s):
#include <ctype.h> // For definition of "isspace"
char *remove_white_spaces(char *str) {
int i = 0, j = 0;
while (str[i]) {
if (!isspace((unsigned char)(str[i])))
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
On the reason for casting the argument to isspace to an unsigned char, see this discussion.
Function removing and replacing any chars in the string.
toRemove - chars to remove
addSpace - replace with space
allowMultiple - allow multiple spaces when replacing more adjanced
characters
allowEdges - allow adding spaces at the from and at the end
char *removeChars(char *str, const char *toRemove, const int addSpace, const int allowMultiple, int const allowEdges)
{
char *rd = str, *wr = str;
int replaced = 0;
if(rd)
{
while(*rd)
{
if(strchr(toRemove, *rd))
{
if(addSpace)
{
if(!replaced || allowMultiple)
{
if(wr != str || (wr == str && allowEdges))
{
*wr++ = ' ';
replaced = 1;
}
}
}
}
else
{
*wr++ = *rd;
replaced = 0;
}
rd++;
}
if(allowEdges) *wr = 0;
else
while((wr - 1) > str)
{
if(*(wr - 1) == ' ') {*(wr - 1) = 0; wr--;}
else break;
}
}
return str;
}
int main(void)
{
char str[] = "%%%%%A sentence\n\n\nwith!##$%^a newline.%%%%%%%";
printf("`%s`\n", removeChars(str,"\n!##$%^", 1, 0, 0));
}
Following the suggestion of #MarkBenningfield I did the following and checked for '\n' and just replaced it with a space.
while (ch != '.') {
msg[i] = ch;
i++;
ch = getchar();
if (ch == '\n') {
ch = ' ';
}
}
Related
I can't figure out how to remove the spaces at the beginning of the sentence without using any libraries other than stdio.h and stdlib.h.
#include <stdio.h>
int main()
{
char text[1000], result[1000];
int c = 0, d = 0;
printf("Enter some text\n");
gets(text);
while (text[c] != '\0') { // till the end of the string
if (text[c] == ' ') {
int temp = c + 1;
if (text[temp] != '\0') {
while (text[temp] == ' ' && text[temp] != '\0') {
if (text[temp] == ' ') {
c++;
}
temp++;
}
}
}
result[d] = text[c];
c++;
d++;
}
result[d] = '\0';
printf("Text after removing blanks\n%s\n", result);
return 0;
}
This piece of code removes all the extra spaces of a sentence.
Example:
input: " this is my program."
output: " this is my program."
EXPECTED OUTPUT: "this is my program."
this code leaves only one space where there were more spaces, but I want to remove all spaces at the beginning as well like in the expected output.
#include <stdio.h>
int main()
{
char text[1000], result[1000];
int c = 0, d = 0;
printf("Enter some text\n");
gets(text);
// no space at beginning
while(text[c] ==' ') { c++; }
while(text[c] != '\0'){
result[d++] = text[c++]; //take non-space characters
if(text[c]==' ') { result[d++] = text[c++]; } // take one space between words
while(text[c]==' ') { c++; } // skip other spaces
}
result[d] = '\0';
printf("Text after removing blanks\n%s\n", result);
return 0;
}
I want to remove all spaces at the beginning as well.
After getting the input, begin processing up to the first non-white-space.
// do not use gets()
fgets(text, sizeof text, stdin);
text[strcspn(text, "\n")] = '\0'; //lop off potential \n
char *ptext = text;
while (isspace((unsigned char) *ptext)) {
ptext++;
}
// now use ptext instead of text for rest of code.
This function will process the input array as you need
void remove_white_space(char *source, char *result) {
int i=0,key=0,k=0;
while (source[i]!='\0') {
if(source[i]==' ') {
if (key== 0) {
if(i==0) {
key=1;
++i;
} else {
key=1;
result[k]=source[i];
++k;
++i;
}
} else
++i;
} else {
key=0;
result[k]=source[i];
++k;
++i;
}
}
result[k]='\0';
}
I need to write program that get Input from user and in case i have quate (") i need to change all the chars inside the quotes to uppercase.
int main()
{
int quoteflag = 0;
int ch = 0;
int i = 0;
char str[127] = { '\0' };
while ((ch = getchar()) != EOF && !isdigit(ch))
{
++i;
if (ch == '"')
quoteflag = !quoteflag;
if (quoteflag == 0)
str[i] = tolower(ch);
else
{
strncat(str, &ch, 1);
while ((ch = getchar()) != '\"')
{
char c = toupper(ch);
strncat(str, &c, 1);
}
strncat(str, &ch, 1);
quoteflag = !quoteflag;
}
if (ch == '.')
{
strncat(str, &ch, 1);
addnewline(str);
addnewline(str);
}
else
{
if ((isupper(ch) && !quoteflag))
{
char c = tolower(ch);
strncat(str, &c, 1);
}
}
}
printf("\n-----------------------------");
printf("\nYour output:\n%s", str);
getchar();
return 1;
}
void addnewline(char *c)
{
char tmp[1] = { '\n' };
strncat(c, tmp, 1);
}
So my problem here is in case my input is "a" this print at the end "A instead of "A" and i dont know why
The problem is that you are using strncat in a weird way. First, strncat will always do nothing on big-endian systems. What strncat does is read the inputs ... as strings. So passing and int (four or eight bytes) into the function, it'll read the first byte. If the first byte is 0, then it'll believe it is the end of the string and will not add anything to str. On little endian systems, the first byte should be the char you want, but on big-endian systems it will be the upper byte (which for an int that holds a value less than 255, will always be zero). You can read more about endianness here.
I don't know why you're using strncat for appending a single character, though. You have the right idea with str[i] = tolower(ch). I changed int ch to char ch and then went through and replaced strncat(...) with str[i++] = ... in your code, and it compiled fine and returned the "A" output you wanted. The source code for that is below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int quoteflag = 0;
char ch = 0;
int i = 0;
char str[127] = { '\0' };
while ((ch = getchar()) != EOF && !isdigit(ch))
{
if (ch == '"')
quoteflag = !quoteflag;
if (quoteflag == 0)
str[i++] = tolower(ch);
else
{
str[i++] = ch;
while ((ch = getchar()) != '\"')
{
char c = toupper(ch);
str[i++] = c;
}
str[i++] = ch;
quoteflag = !quoteflag;
}
if (ch == '.')
{
str[i++] = '.';
str[i++] = '\n';
str[i++] = '\n';
}
else
{
if ((isupper(ch) && !quoteflag))
{
char c = tolower(ch);
str[i++] = c;
}
}
}
printf("\n-----------------------------");
printf("\nYour output:\n%s", str);
getchar();
return 1;
}
You should delete the ++i; line, then change:
str[i] = tolower(ch);
To:
str[i++] = tolower(ch);
Otherwise, since you pre-increment, if your first character is not a " but say a, your string will be \0a\0\0.... This leads us on to the next problem:
strncat(str, &ch, 1);
If the input is a", then strncat(str, &'"', 1); will give a result of \"\0\0... as strncat will see str as an empty string. Replace all occurrences with the above:
str[i++] = toupper(ch);
(The strncat() may also be technically undefined behaviour as you are passing in an malformed string, but that's one for the language lawyers)
This will keep track of the index, otherwise once out of the quote loop, your first str[i] = tolower(ch); will start overwriting everything in quotes.
I have this string: print "Foo cakes are yum"
I need to somehow strip all extra whitespace but leave text between quotes alone. This is what i have so far:
char* clean_strip(char* string)
{
int d = 0, c = 0;
char* newstr;
while(string[c] != '\0'){
if(string[c] == ' '){
int temp = c + 1;
if(string[temp] != '\0'){
while(string[temp] == ' ' && string[temp] != '\0'){
if(string[temp] == ' '){
c++;
}
temp++;
}
}
}
newstr[d] = string[c];
c++;
d++;
}
return newstr;
}
This returns this string: print "Foo cakes are yum"
I need to be able to skip text between thw quotes so i get this: print "Foo cakes are yum".
Here is the same question but for php, i need a c answer: Remove spaces in string, excluding these in specified between specified characters
Please help.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* clean_strip(char* string)
{
int d = 0, c = 0;
char* newstr = malloc(strlen(string)+1);
int quoted = 0;
while(string[c] != '\0'){
if (string[c] == '"') quoted = !quoted;
if(!quoted && string[c] == ' '){
int temp = c + 1;
if(string[temp] != '\0'){
while(string[temp] == ' ' && string[temp] != '\0'){
if(string[temp] == ' '){
c++;
}
temp++;
}
}
}
newstr[d] = string[c];
c++;
d++;
}
newstr[d] = 0;
return newstr;
}
int main(int argc, char *argv[])
{
char *input = "print \"Foo cakes are yum\"";
char *output = clean_strip(input);
printf(output);
free(output);
return 0;
}
This will produce the output:
print "Foo cakes are yum"
It works by looking for the " character. If it's found it toggles the variable quoted. If quoted is true, then the whitespace removal is skipped.
Also, your original function never allocates memory for newstr. I added the newstr = malloc(...) part. It is important to allocate memory for strings before writing to them.
I simplified your logic a little.
int main(void)
{
char string[] = "print \"Foo cakes are yum\"";
int i = 0, j = 1, quoted=0;
if (string[0] == '"')
{
quoted=1;
}
for(i=1; i< strlen(string); i++)
{
if (string[i] == '"')
{
quoted = 1-quoted;
}
string[j] = string[i];
if (string[j-1]==' ' && string[j] ==' ' && !quoted)
{
;
}
else
{
j++;
}
}
string[j]='\0';
printf("%s\n",string);
return 0;
}
I need to read the text and find if there is more than one space between the words.
If there is change it to one.
For example if I have a text:
My name is Lukas
Program should change it to:
My name is Lukas
Any ideas?
while (*str) {
if (*str != ' ' || str[1] != ' ') *newstr++ = *str;
str++;
}
*newstr = 0;
j = 0;
for(i=0; myStr[i] != '\0'; i++) {
if(myStr[i] == ' ' && myStr[i+1] == ' ')
continue;
newStr[j] = myStr[i];
j++;
}
And don't forget to add '\0' (Which indicates the end of the string) to the end of newStr
isspace from <ctype.h> could be useful here. Here is a possible implementation:
void delete_multiple_spaces(char *dst, const char *src)
{
int previous = 0;
int c;
while ((c = *src++) != '\0')
{
if (isspace(c) && !previous)
{
previous = 1;
}
else
{
if (previous)
{
*dst++ = ' ';
previous = 0;
}
*dst++ = c;
}
}
*dst = '\0';
}
From your earlier query, I modified the logic to fit your requirement. Hope this helps.
FILE *in;
char ch,str[100],cw;
int j,i = 0;
int isSpace = 0;
in=fopen("duom.txt","r");
if(in){
while(!feof(in)){
ch=getc(in);
if(isSpace)
isSpace = (isSpace & (ch == ' '));
if(!isSpace) {
str[i] = ch;
i++;
}
if(ch == ' ')
isSpace = 1;
}
for(j=0;j<i;j++){
printf("%c",str[j]);
}
char *(strdupcompact) (const char *c)
{
int i; int p;
for (i = 0, p = 0; c[i]; i++, p++)
{
if (c[i] == ' ') while (c[i+1] == ' ') i++;
}
char *newstr = malloc(p + 1);
for (i = 0, p = 0; c[i]; i++, p++)
{
newstr[p] = c[i];
if (c[i] == ' ') while (c[i+1] == ' ') i++;
}
newstr[p] = 0;
return newstr;
}
Makes a malloced copy of your string.
So I'm trying to find all instances of a word using this section of code
fseek(src, 0, SEEK_END);
int size = ftell(src);
fseek(src, 0, SEEK_SET);
int line = 0;
int i = 0;
char ch = ' ';
char *word;
char lastch = 'x';
int j = 0;
int lines[getLines(src)];
for(i = 0; i < getLines(src); i++){
lines[i] = -1;
}
for(i = 0; i < size; i++){
ch = fgetc(src);
printf("%s %c", word, '\n');
if(!isspace(lastch) && isspace(ch)){
if(strcmp(word, find) == 0){
if(lines[j - 1] != line){
lines[j] = line;
j++;
}
}
}else{
if(isspace(lastch) && isspace(ch)){
continue;
}else if(isspace(lastch) && !isspace(ch)){
word = "";
append(word, ch);
}else if(!isspace(lastch) && !isspace(ch)){
append(word, ch);
}
}
lastch = ch;
}
Where as append() is
char *append(const char *s, char c) {
int len = strlen(s);
char buf[len+2];
strcpy(buf, s);
buf[len] = c;
buf[len + 1] = 0;
return strdup(buf);
}
Could anyone explain to me why the String word does not get any characters added into it?
I'm pretty sure it has to do with the append function, thanks.
So after having read my comment, read my answer as well:
word = "";
append(word, ch);
doesn't do what you think it does. It does not append a character to word itself, instead it appends a character to a writable copy of word. You should really write
} else if(isspace(lastch) && !isspace(ch)) {
word = append("", ch);
} else if(!isspace(lastch) && !isspace(ch)) {
char *tmp = append(word, ch);
free(word);
word = tmp;
}
instead. Also, please use whitespaces and indentation properly, it's hard to read your code.