How to remove quotes from a string in C - c

I am trying to remove all quotes in a given line except a backslash followed by a quote
what I have done is this
for (int i = 0; i < lineLength; i ++) {
if (line[i] == '"' ) {
if (line[i-1] == '\\') // if \" is used
line[i-1] = '"'; // then print \
line[i] = '\0'; // or 0
}
}
This removes all characters in the line.. what can I do to remove only quotes?
Any help would be appreciated...

Your problem is line[i] = '\0'; - it terminates the string.
If you want to remove characters from a C string, you need to hold two indices - one for reading and one for writing, loop over the read index reading each character, and write only the ones you want to keep using the second index.
Something along the lines of:
int j = 0;
for (int i = 0; i < lineLength; i ++) {
if (line[i] != '"' && line[i] != '\\') {
line[j++] = line[i];
} else if (line[i+1] == '"' && line[i] == '\\') {
line[j++] = '"';
} else if (line[i+1] != '"' && line[i] == '\\') {
line[j++] = '\\';
}
}
//You missed the string termination ;)
if(j>0) line[j]=0;

You are setting the first " character you find to the null character, terminating the string.
Also an aside, but line[i-1] could cause a segmentation fault when i == 0, or it could happen to contain \ in which case the first quote wouldn't be stripped.
Something like this will do what you want:
char *lineWithoutQuotes = malloc(strlen(line));
int i, j;
if(line[0] != '"')
lineWithoutQuotes[0] = line[0];
for(i = j = 1; i < strlen(line); i++){
if(line[i] == '"' && line[i-1] != '\\')
continue;
lineWithoutQuotes[j++] = line[i];
}

The normal technique using indexes is:
int j = 0;
for (int i = 0; i < lineLength; i++)
{
if (line[i] == '\\')
{
line[j++] = line[i++];
line[j++] = line[i];
if (line[i] == '\0')
break;
}
else if (line[i] != '"')
line[j++] = line[i];
}
line[j] = '\0';
Using pointers (and not needing lineLength), it is:
char *dst = line;
char *src = line;
char c;
while ((c = *src++) != '\0')
{
if (c == '\\')
{
*dst++ = c;
if ((c = *src++) == '\0')
break;
*dst++ = c;
}
else if (c != '"')
*dst++ = c;
}
*dst = '\0';
Or minor variations on those themes...

int newPos = 0;
for (int oldPos = 0; oldPos < lineLength; oldPos++) {
if (!(line[newPos] == '"' && (!newPos || line[newPos-1] == '\\'))) {
line[newPos] = line[oldPos];
newPos++;
}
}
line[newPos] = 0;

Related

How to find unique word number of occurrences?

Can't figure out the bug in my code. Every time I input a sentence, the count does increment but the word adds the first letter of the previous word and increments one letter every time. How do I fix this?
void numberOfWordOccurrences(char str[MAX_CHAR]) {
int count = 0, i = 0, j = 0;
char uniqueToken[99][999];
int tokenCount[99] = {0};
while(str[i] != '\0') {
char token[999];
while(str[i] != ' ' && str[i] != '\0') {
token[j++] = str[i++];
}
if(token[j - 1] == ':' || token[j - 1] == ',' || token[j - 1] == '.' || token[j - 1] == ';' || token[j - 1] == '?' || token[j - 1] == '!') {
token[j - 1] = '\0';
}
//null
token[j] = '\0';
//flag
int flag = -1;
for(j = 0; j < count; j++) {
if(strcmp(uniqueToken[j], token) == 0) {
//if flag is valid, then...
flag = j;
tokenCount[flag] = token[flag] + 1;
break;
}
}
if(flag <= 1) {
tokenCount[count] = tokenCount[count] + 1;
strcpy(uniqueToken[count++], token);
}
i++;
}
}```
first you have to set j=0 inside of your main while loop ,otherwise when you go inside of this loop for(j = 0; j < count; j++) jwill in increase , so here token[j++] = str[i++]; you won't start to copy str in token from j=0 that is why you have previous words letters.
second I believe this condition if(flag <= 1) should be if(flag == -1) because if for example first and fifth word are similar flag would be 0 and again that string would be copied in uniqueToken.
also pay attention if you reach \0 you with your two i++ you will pass it and here while(str[i] != '\0') you won't check it so I suggest while(str[i-1] != '\0') also before sending string check if there is anything in it(in a case str[0]='\0'.
look
void numberOfWordOccurrences(char str[]) {
int count = 0, i = 0, j = 0;
char uniqueToken[99][999];
int tokenCount[99] = { 0 };
while (str[i-1] != '\0') {
j = 0;
char token[999];
while (str[i] != ' ' && str[i] != '\0') {
token[j++] = str[i++];
}
if (token[j - 1] == ':' || token[j - 1] == ',' || token[j - 1] == '.' || token[j - 1] == ';' || token[j - 1] == '?' || token[j - 1] == '!') {
token[j - 1] = '\0';
}
//null
token[j] = '\0';
//flag
int flag = -1;
for (j = 0; j < count; j++) {
if (strcmp(uniqueToken[j], token) == 0) {
//if flag is valid, then...
flag = j;
tokenCount[flag] = token[flag] + 1;
break;
}
}
if (flag == -1) {
tokenCount[count] = tokenCount[count] + 1;
strcpy(uniqueToken[count++], token);
strcpy(uniqueToken[count], "\0");
}
i++;
}
}

Program to remove trailing blanks not working! :(

Recently I've been working on an excercise from K & R's C book, wich states: write a program to remove trailing blanks/ tabs from each line of input, bla bla bla.
I've tried A LOT of ways using functions and didn't work. So I decided to put everything inside main() and it just doesn't work either! Here's the code:
#include <stdio.h>
#define MAX_INPUT 100
#define ACTIVE 1 //quit with Ctrl + C
void main(){
int i, nb, nt;
char c;
char line[MAX_INPUT];
char corrected[MAX_INPUT];
while(ACTIVE){
//get current line
for(i = 0; i < MAX_INPUT - 1 && (c = getchar()) != EOF && c != '\n'; i++)
line[i] = c;
if(c == '\n'){
line[i] = c;
}
line[i + 1] = '\0';
//correct current line
nb = nt = 0;
for(i = 0; line[i] != '\0'; i++){
if(line[i] == ' '){
nb++;
if(nb == 1)
corrected[i] == line[i];
}
else{
if(line[i] == '\t'){
nt++;
if(nt == 1)
corrected[i] == line[i];
}
else
corrected[i] == line[i];
}
}
corrected[i] == '\n';
corrected[i + 1] == '\0';
//print corrected line
printf("%s", corrected);
}
}
So, by the time I want to print the "corrected" version of the current line, it prints this instead:
�
I'd really appreciate the help. I've been trying this the whole week and it's driving me crazy the fact I can't find the error xD
Thanks for your attention, folks! :)
Change
corrected[i] == line[i];
corrected[i] == '\n';
corrected[i + 1] == '\0';
to
corrected[i] = line[i];
corrected[i] = '\n';
corrected[i + 1] = '\0';
== is an equality operator, while = is an assignment operator.
You are using the comparaison operator == instead of the assignment operator =.

Escaping characters in C

I want to replace all special characters in a string with their escaped equivalences (\n \t \\ \"). My idea is to use reader and writer and then put \\ before any special character. I use an dynamic array/char pointer.
Since I am not so confident in my understanding of pointers I still tend to use sometimes more often arrays than pointers.
As usual with C I get mostly (only) garbage as an output. Where do I get this undefined behavior from? My code so far:
char *escapeChars(const char *src)
{
int i, counter = 0, j = 0;
size_t size = strlen(src) + 1;
char pr[size], *pw;
pr[0] = '\0';
strcat(pr, src); /*to get the constness away*/
pw = pr;
for(i = 0; i < ((int) sizeof(pr)); i++){
if(pr[i] == '\n' || pr[i] == '\t' || pr[i] == '\\' || pr[i] == '\"'){
counter++;
}
}
pw = malloc(sizeof(pr) + (size_t) counter);
for(i = 0; i <((int) sizeof(pr)); i++){
if(pr[i] != '\n' || pr[i] != '\t' || pr[i] != '\\' || pr[i] != '\"'){
pw[i+j] = pr[i];
} else {
pw[i+j] = '\\';
pw[i+j+1] = pr[i];
j++;
}
}
pw[i + j] = '\0';
return pw;
}
As an output I get totally wrong stuff. And I believe it fails when encounters the first special chararacter.
Original string: Some
string with "special characters". And \.
Result: Some
str
If anything is even slightly unclear, notify me.
You need to special case the replacement of '\n' to '\\' + 'n' etc.
There is no need to make a local copy of src to scan for special characters. You can simplify the code this way:
char *escapeChars(const char *src) {
int i, j;
char *pw;
for (i = j = 0; src[i] != '\0'; i++) {
if (src[i] == '\n' || src[i] == '\t' ||
src[i] == '\\' || src[i] == '\"') {
j++;
}
}
pw = malloc(i + j + 1);
for (i = j = 0; src[i] != '\0'; i++) {
switch (src[i]) {
case '\n': pw[i+j] = '\\'; pw[i+j+1] = 'n'; j++; break;
case '\t': pw[i+j] = '\\'; pw[i+j+1] = 't'; j++; break;
case '\\': pw[i+j] = '\\'; pw[i+j+1] = '\\'; j++; break;
case '\"': pw[i+j] = '\\'; pw[i+j+1] = '\"'; j++; break;
default: pw[i+j] = src[i]; break;
}
}
pw[i+j] = '\0';
return pw;
}
Note that you should also escape some other characters: '\r', and the non printing or non portable characters in the range 1 to 31 and 127 to 255 for ASCII. Escaping these as octal sequences is more work but manageable at your skill level.

Counting symbols and empty lines from input text via gets

The program should print the number of empty lines and certain operators from the input text. I got the problem of empty lines fixed but I'm facing issues with the opperators. I guess it is something wrong with the break. I would appreciate any good ideas for fixing the code. Sorry if such a thread already exists but I checked and couldn't get a solution. Thanks in advance!
char c,line[300];
int emptyLine = 0;
int operators = 0;
printf("Input your text and press ctr+Z on a new line when done: \n");
while(gets(line)) {
int i = 0;emptyLine++;
for (i = 0; i < strlen(line); i++) {
if(line[i] == '+'|| line[i] == '-' || line[i] == '/' || line[i] == '*' || line[i] == '%')
{
operators++;
}
if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ') {
emptyLine--;
break;
}
}
}
printf("The number of empty lines is: %d",emptyLine);
printf("\nThe number of opperators is: %d",operators);
Try something like this:
char c,line[300];
int emptyLine = 0;
int operators = 0;
printf("Input your text and press ctr+Z on a new line when done: \n");
while(gets(line)) {
bool isEmpty = true; // Assume empty line
for (int i = 0; 0 != line[i]; i++) {
if (!isspace(line[i])) {
isEmpty = false; // Line not empty
}
if (line[i] == '+'|| line[i] == '-' || line[i] == '/' || line[i] == '*' || line[i] == '%') {
operators++;
}
}
if (isEmpty) {
emptyLine += 1;
}
}
printf("The number of empty lines is: %d",emptyLine);
printf("\nThe number of operators is: %d",operators);

Change more than one space in between words into one

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.

Resources