Ansi C - Removing new line character and changing it to a space - c

void createTextFile()
{
FILE *textFile = fopen("/Users/Trenae_Alyxandria_Johnson/Desktop/myTextFile.txt", "w");
char c;
fputs("1\n2\n3\n4\n5", textFile);
fclose(textFile);
textFile = fopen("/Users/Trenae_Alyxandria_Johnson/Desktop/myTextFile.txt", "r");
while (c != EOF)
{
c = fgetc(textFile);
}
for(int i = 0; i < 6; i++)
{
if(c(i) == '\n')
{
c(i) = ' ';
}
}
printf("%c" , c);
fclose(textFile);
}
I'm trying to remove the new line char and change it to a space. I know it's not an array but I guess I'm asking how do I parse through the file, to see when I get to the new line then remove it and replace it with a space so the 1 - 5 that was first entered can now appear on one line with a space char separating each.
ERRORS:
error: subscripted
value is not an array, pointer, or vector
if(c[i] == '\n')

The for loop is not needed. You can remove it. `
c = fgetc(textFile);
while (c != EOF){
if(c == '\n')
{
c = ' ';
}
printf("%c" , c);
c = fgetc(textFile);
}
A char is not a string, a char is a character. So c[i] does not mean anything. It you wish to store a string, use an array of char terminated by \0 :
char s[100];
s[99]='\0'
printf("%s",s);

int c;//return of fgetc type is int
while(EOF!=(c=fgetc(textFile)))
putchar(c == '\n' ? ' ' : c);

Related

Solving KNKING exercise 14, chapter 8. Reverse the words

I'm reading K.N.King C programming and I have an issue about it.
I'm solving project 5, chapter 12 which is modify project 14 from chapter 8 by using the pointer .
Project 8.14
Write a program that reverses the words in a sentence:
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you can't swallow a cage can you?
Hint: Use a loop to read
the characters one by one and store them in a one-dimensional char
array. Have the loop stop at a period, question mark, or exclamation
point (the "terminating character"), which is saved in a separate char
variable. Then use a second loop to search backward through the array
for the beginning of the last word. Print the last word, then search
backward for the next-to-last word. Repeat until the beginning of the
array is reached. Finally, print the terminating character.
#include <stdio.h>
#include <ctype.h>
#define N 100
int main()
{
char arr[N] = {0};
char *p, *q, mark = 0;
int c;
p = arr;
while((c = getchar()) != '\n' && p < arr + N)
{
if(c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = c;
}
*p = '\0';
while(p >= arr)
{
while(*--p != ' ' && p != arr);
q = p == arr ? arr : p + 1;
while(*q != '\0' && *q != ' ')
{
printf("%c", *q++);
}
if(p >= arr)
printf(" ");
}
printf("\b%c", mark);
printf("\n");
}
the problem is if I enter enter a sentence "My name is jiyong!", expected output is "jiyong is name My!" but the output always has '\xxx'. How can I get rid off? and what is these '\xxx' things?
ran under Xcode 12.4
The second loop looks too complicated to me. You are required to scan the string backwards and print every word found, right? But you're not required to retain the whole sentence...?
So we can replace every space character with zero, thus terminating each word.
while((c = getchar()) != '\n' && p < arr + N)
{
if(c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = (c == ' ') ? '\0' : c;
}
*p = '\0';
Then we can seek words backwards and print them as strings instead of iterating over their characters:
while(--p > arr) // all words except the first one
{
if(!*p && p[1]) //p[1] or *(p + 1)
printf("%s ", p+1);
}
printf("%s", arr); // the first word goes last
if(mark)
printf("%c", mark);
printf("\n");
I assumed p gets incremented at least once in the first loop, that is the input line is never empty. But that seems a valid assumption (although not very safe) as the input is defined as 'a sentence', so it should not be empty...

fgets() and scanf() not working properly in unison. Buffer problem encountered

My assignment: -
Write a program that replaces the occurence of a given character (say
c) in a primary string (say PS) with another string (say s).
Input: The first line contains the primary string (PS) The next line
contains a character (c) The next line contains a string (s)
Output: Print the string PS with every occurence of c replaced by s.
Test case 1: -
Input: -
abcxy
b
mf
Expected output: -
amfcxy
Test case 2: -
Input: -
Al#bal#20owL
l
LL
Expected output: -
ALL#baLL#20owL
My code below: -
#include <stdio.h>
#include <stdlib.h>
int main() {
char PS[101];
char c;
char S[11];
fgets(PS, 101, stdin); //PS value input.
scanf("%c", &c);
if (c == '\n' || c == '\0') {
scanf("%c", &c); //Clearing the buffer. I want the real value of 'c' from STDIN not '\n'
}
fgets(S, 11, stdin); //S value input.
int i = 0;
while (PS[i] != '\0') { //Removing the '\n' from PS
if (PS[i] == '\n') {
PS[i] = '\0';
break;
}
i++;
}
i = i - 1; //i now holds the value of the size of the string PS (excluding '\0')
int j = 0;
while (S[j] != '\0') {
if (S[j] == '\n') {
S[j] = '\0';
break;
}
j++;
}
j = j - 1; //j now holds the value of the size of the string S (excluding '\0')
int k = 0; //work as an initializer
int move = 0; //work as an initializer.
while (PS[k] != '\0') { //This loops checks the whole array for the same character mentioned in char 'c'
if (PS[k] == c) {
for (move = i; move > k; move --) { //This loop advances the all the characters in PS by '(j - 1)' steps to make space for string S characters.
PS[move + (j - 1)] = PS[move];
}
for (move = 0; move < j; move++) { //This loop adds all the characters of string S into string PS at the relevant place.
PS[k + move] = S[move];
}
i = i + (j - 1); // 'i' now holds the new value of size of string PS after adding all the characters of string S.
}
k++;
}
puts(PS);
return 0;
}
Now the problem is that the code is not taking the input for string S.
After inputting first 2 inputs, it executes and gives a gibberish answer. I cannot figure out the bug, but what I do know is that there is some issue related to the buffer in C. Please help.
Edit: -
Thanks to #WeatherVane I have now edited the code with this: -
scanf("%c", &c);
if (c == '\n' || c == '\0') {
scanf("%c", &c); //Clearing the buffer. I want the real value of 'c' from STDIN not '\n'
}
char x;
x = getchar(); //New addition. It eats the '\n' after scanf().
fgets(S, 11, stdin); //S value input.
Now my code is working fine but the output is still not correct. It is sometimes failing to copy the last char from string S or giving me gibberish output.
The problem with the code was: -
i = i - 1; //i now holds the value of the size of the string PS (excluding '\0')
j = j - 1; //j now holds the value of the size of the string S (excluding '\0')
The value of i and j are the true values of the size of string PS and string S; not i = i - 1 and j = j - 1.
Lesson learnt from this assignment: -
scanf() does not treat '\n' in any way. It WILL be left in the
buffer.
If possible use fgets and then remove '\n' from your respective array/pointer.
Be extra careful of your C buffer when dealing with chars and strings.
The final correct code is: -
#include <stdio.h>
#include <stdlib.h>
int main()
{
char PS[101];
char c;
char S[11];
fgets(PS, 101, stdin); //PS value input.
scanf("%c", &c);
if(c == '\n' || c == '\0')
{
scanf("%c", &c); //Clearing the buffer. I want the real value of 'c' from STDIN not '\n'
}
char x;
x = getchar(); //New addition. It eats the '\n' after scanf().
fgets(S, 11, stdin); //S value input.
int i = 0;
while(PS[i] != '\0') //Removing the '\n' from PS
{
if(PS[i] == '\n')
{
PS[i] = '\0';
break;
}
i++;
}
i = i; //i now holds the value of the size of the string PS (excluding '\0')
int j = 0;
while(S[j] != '\0')
{
if(S[j] == '\n')
{
S[j] = '\0';
break;
}
j++;
}
j = j; //j now holds the value of the size of the string S (excluding '\0')
int k = 0; //work as an initializer
int move = 0; //work as an initializer.
while(PS[k] != '\0') //This loops checks the whole array for the same character mentioned in char 'c'
{
if(PS[k] == c)
{
for(move = i; move > k; move --) //This loop advances the all the characters in PS by '(j - 1)' steps to make space for string S characters.
{
PS[move + (j - 1)] = PS[move];
}
for(move = 0; move < j; move++) //This loop adds all the characters of string S into string PS at the relevant place.
{
PS[k + move] = S[move];
}
i = i + (j - 1); // 'i' now holds the new value of size of string PS after adding all the characters of string S.
}
k++;
}
puts(PS);
return 0;
}
Warning: -
The above code is very unoptimised and unreadable. Do not use it for
long term projects. It just "works".
Any suggestions for improvements of the above code are welcomed in
the comments.
Further necessary reading material recommended if you face any issue regarding C buffer in the future: -
Read 1
Read 2

Copying input to output without unnecessary Spaces in C

I'm trying to write a program in C that copies its input to its output while replacing each string of one or more Spaces with a single Space.
My code isn't doing that but is instead taking away every second character.
This is my code:
#include <stdio.h>
main()
{
int c;
int lastc;
lastc = 0;
while(getchar() != EOF){
c = getchar();
if(c == 32 && lastc == 32)
;
else
putchar(c);
lastc = c;
}
}
Your loop should look like:
while((c = getchar()) != EOF){
if(c == 32 && lastc == 32)
;
else
putchar(c);
lastc = c;
}
In your version you get a char with getchar while checking the condition for the while loop and then as a next step you again get a char with getchar. So the first one is not used in your code. Therefore it is taking away every second character.
Keep running in while loop until you get non-space character and print just one space after you get out.
int main()
{
int c;
bool space=false;
while ((c=getchar()) != EOF) {
while (isspace(c)) {
space = true;
c = getchar();
}
if (space) {
putchar(' ');
space = false;
}
putchar(c);
}
return 0;
}
I use fgets() function to getting string from input i.e stdin and store in the scroll string.
Then you must implement a way to analyze string to find spaces in it.
When you find first space, increase index if you face another space.
This is the code.
Code
#include <stdio.h>
int main(void){
char scroll[100];// = "kang c heng junga";
fgets(scroll, 100, stdin);
printf ("Full name: %s\n", scroll);
int flag = 0;
int i=0;
while (scroll[i] != '\0')
{
if (scroll[i] == ' ' )
flag=1;//first space find
printf("%c",scroll[i]);
if (flag==0){
i++;
}else {
while(scroll[i]==' ')
i++;
flag=0;
}
}
return 0;
}
Sample input: Salam be shoma doostane aziz
Program output: Salam be shoma doostane aziz
[Edit]
Use new string st to hold space eliminated string an print as output.
Also this code work for Persian string.
char scroll[100]={0};// = "kang c heng junga";
printf("Enter a string: ");
fgets(scroll, 100, stdin);
printf ("Original string: %s\n", scroll);
char st[100]={0};
int flag = 0;
int i=0;
int j=0;
while (scroll[i] != '\0')
{
if (scroll[i] == ' ' )
flag=1;//first space find
st[j]=scroll[i];
j++;
if (flag==0){
i++;
}else {
while(scroll[i]==' ')
i++;
flag=0;
}
}
printf("Eliminate Spaces: %s", st);

Why is my wc implementation giving wrong word count?

Here is a small code snippet.
while((c = fgetc(fp)) != -1)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
else
{
if(c == ' ' && prevC != ' ') wCount++; // word count
}
prevC = c; // previous character equals current character. Think of it as memory.
}
Now when I run wc with the file containing this above snippet code(as is), I am getting 48 words, but when I use my program on same input data, I am getting 59 words.
How to calculate word count exactly like wc does?
You are treating anything that isn't a space as a valid word. This means that a newline followed by a space is a word, and since your input (which is your code snippet) is indented you get a bunch of extra words.
You should use isspace to check for whitespace instead of comparing the character to ' ':
while((c = fgetc(fp)) != EOF)
{
cCount++;
if (c == '\n')
lCount++;
if (isspace(c) && !isspace(prevC))
wCount++;
prevC = c;
}
There is an example of the function you want in the book: "Brian W Kernighan And Dennis M Ritchie: The Ansi C Programming Language". As the author says: This is a bare-bones version of the UNIX program wc. Altered to count only words is like this:
#include <stdio.h>
#define IN 1 /* inside a word */
#define OUT 0 /* outside a word */
/* nw counts words in input */
main()
{
int c, nw, state;
state = OUT;
nw = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d\n", nw);
}
Instead of checking for spaces only you should check for escape sequences like \t \n space and so on.
This will give the correct results.
You can use isspace() from <ctype.h>
Change the line
if(c == ' ' && prevC != ' ') wCount++;
to
if(isspace(c) && !(isspace(prevC)) wCount++;
This would give the correct results.
Don't forget to include <ctype.h>
You can do:
int count()
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0;
char c;
FILE *fp = fopen ("text", "r");
if (fp == NULL)
{
printf ("Failed to open file\n");
return -1;
}
while((c = fgetc(fp)) != EOF)
{
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
printf ("line : %u\n", lCount);
printf ("word : %u\n", wCount);
printf ("char : %u\n", cCount);
return 0;
}

C: segmentation fault

I've created this function to read a word. I got segmentation fault and I can't find the problem. Here's what I've done.
void LeeCaracter(FILE * fp, char * s)
{
char c;
int i = 0;
c = fgetc(fp);
while(c==' ' || c=='\t' || c=='\n')
c = fgetc(fp);
while(c!=' ' && c!='\n')
{
s[i] = c;
i++;
c = fgetc(fp);
}
s[i] = '\0';
}
s is a pointer parameter, as I have to use it later. Is it correct to write it just with one *? Thanks for your help!
*And what about if I wanted to know the character that follows the word(' ' or '\n')? I added this after the while loop:
"printf("%c",c);"
but it doesn't print anything. Any ideas?
Consider:
while(c==' ' || c=='\t' || c=='\n')
c = fgetc(fp);
So, at this point, two things that c is not are ' ' and '\n'. Then:
while(c!=' ' && c!='\n')
{
s[i] = c;
i++;
}
Since the value of c does not change in the loop, the while condition is always true. Meaning that pretty quickly, s[i] will go out of bounds. You need to check against the length of s, probably by getting that passed in as a parameter (not to mention, rethink your algorithm a bit -- probably you want to fgetc more inside the loop).
You have to make sure that the 's' has enough space for containing a word with maximum characters in the input file. Then you need to make sure that you check for 'End Of File'. Here is a working version. I hope it works for you as well.
#include <stdio.h>
void LeeCaracter(FILE * fp, char * s)
{
char c;
int i = 0;
c = fgetc(fp);
if (feof(fp)) return;
while (c == ' ' || c == '\t' || c == '\n')
c = fgetc(fp);
while (!feof(fp) && (c != ' ' && c != '\n')) {
s[i++] = c;
c = fgetc(fp);
}
s[i] = '\0';
printf("%s\n", s);
}
int main(void)
{
char s[128]; /* assuming no word is larger than this size */
FILE *fp = fopen("/usr/share/dict/words", "r");
while (!feof(fp)) {
LeeCaracter(fp, s);
}
return 0;
}

Resources