I have 2 C functions that interact with one another. The first a writer function takes an int n and writes "Hellohello" n number of times. The reader function reads whatever is input to it, and every 50 characters inserts a newline character.
My current dilemma is that when I have a number of characters that is a factor of 50 my reader is putting an extra newline character in when I do not want it to. I have tried multiple different ways to remedy this and nothing I have attempted has worked as of yet. What I'm providing is my reader code without any of my attempted fixes as well as an example of what the problem is.
I do have to use getchar and putchar, I understand that there would be easier ways if I wasn't using them but it is unfortunately a must. Any assistance as to how I should approach this or something I should have thought about are greatly appreciated.
reader code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int count = 0;
char c;
while (c != EOF)
{
c = getchar();
if (count == 50)
{
putchar('\n');
count = 0;
}
putchar(c);
count++;
}
}
example output:
[88] [cbutc1#courses2016:~/csc412]$ writer 10 | reader1
HellohelloHellohelloHellohelloHellohelloHellohello
HellohelloHellohelloHellohelloHellohelloHellohello
▒[89] [cbutc1#courses2016:~/csc412]$
edit: clarity
When you read (getchar) a newline you print a newline (putchar).
Also, 'c' should be declared 'int'' so it is big enough to hold EOF properly.
Also the value of 'c' is undefined the first time through the loop and you print "EOF'", use:
while ((c = getchar()) != EOF) { …
Additionally, you should use int main ( void ) { …
And the C language does have "classes", only functions.
Simply changed the if statement that was checking the count to include a check for newline characters. This remedied the problem that was occuring.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int count = 0;
char c;
while (c != EOF)
{
c = getchar();
if ((count == 50) && (c != '\n'))
{
putchar('\n');
count = 0;
}
putchar(c);
count++;
}
}
Related
I scraped a website to get some mcqs for a c assignment. I wrote the data to a plaintext file separating every entry with null chars.
The pattern is:
Question with choices NULL Answer NULL Question...
Here is a sample of the file. the red dots are '\0' chars:
Here is a link to get the full file.
Code to read this file in C:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Question{
char question[1000];
char answer;
};
int main(){
struct Question questions[100];
FILE *fp;
char buffer[1000],choice;
int ch,i=0,c=1,k=0,score=0;
fp=fopen("quiz_questions.txt","r");
ch = 1;
while (ch != EOF)
{
ch = getc(fp);
buffer[i]=ch;
i++;
if(ch=='\0'){
buffer[i]='\0';
c++;
i=0;
continue;
}
if(c%2){ //question
strcpy(questions[k].question,buffer);
}
else{ //answer
questions[k].answer=buffer[0];
k++;
}
}
for(i=0;i<35;i++){
printf("\nQuestion:\n%s\nAnswer: %c\n",questions[i].question,questions[i].answer);
}
return 0;
}
OUTPUT:
What am I missing? Help please. It seems the buffer isn't getting null terminated properly and is retaining chars from last assignment.
PS: Is there a better way to consume this data from c? Scraping done via python.
EDIT: I now realize writing a separate answerkey file would have been much better. Stupid me.
strcpy(questions[k].question,buffer);
This statement is executed for every single character you read (if c is odd). At this point, buffer is not null terminated yet (and not a string).
ch = getc(fp);
buffer[i]=ch;
These two lines write to buffer[i] even if the end of file was reached. You only check for EOF after having processed it as if it were a normal character.
i++;
if(ch=='\0'){
buffer[i]='\0';
This is redundant. If ch is '\0', then you've just null terminated buffer in buffer[i]=ch;. There's no need to add another '\0'.
Modified version of your code to solve the problem:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Question{
char question[1000];
char answer;
};
int main()
{
struct Question questions[100];
FILE *fp;
char buffer[1000],choice;
int ch,i=0,c=0,k=0,score=0; **<-- EDIT:change done here to initialize c = 0**
fp=fopen("quiz_questions.txt","r");
ch = 1;
while (ch != EOF)
{
ch = getc(fp);
buffer[i]=ch;
i++;
if(ch =='\0')
{
//buffer[i]='\0'; <-- Change done here, unnecessary assignment
c++;
i=0;
if(c%2) <-- Change done here, moved inside if (ch == '\0') case
{
//question
strcpy(questions[k].question,buffer);
}
else
{
//answer
questions[k].answer=buffer[0];
k++;
}
}
}
for(i=0;i<35;i++)
{
printf("\nQuestion:\n%s\nAnswer: %c\n",questions[i].question,questions[i].answer);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int ascii[255]; //starts as empty table, will hold all the character occurences
memset(ascii, 0, sizeof(ascii)); // sets all table values to 0
int c=0;
int i=0;
while (getchar() !=EOF){
c=getchar();
ascii[c]=(ascii[c]+1);
}
for (i=0;i<255;i++){
printf("%d;",ascii[i]);
}
return 0;
}
Hello, ive created the above code to check how many times each character occurs in a .txt file, but im getting really erratic behaviour, the numbers that im getting dont reflect the contents of file at all. Could you tell me where is my error?
You have two getchar() calls, so you are missing one character in each call, change this
while (getchar() != EOF)
to
while ((c = getchar()) != EOF)
and remove the next line
c = getchar();
I have to input values whose frequency i don't know...
For example first input: 1 32 54 65 6
second input: 2 4 5
What i first thought was, scan the values, if new line '\n' then break the loop, but that didn't go so well, so instead i said i use characters, then i typecast to get the number but the problem with this also came that it scan one character by one and if its its a negative value its also a problem;
Something like this
#include <stdio.h>
int main(){
int myarray[20];
int i=0, data;
while(1){
scanf("%d", &data);
if (data == '\n') break;
myarray[i]=data;
}
return 0;
}
but then, scanf jumps all the special characters and look for only ints... is there a way to scan ints to an array and when there is a newline it stops?
My advice, go for fgets().
Read the whole line from the input
Tokenize using space [] [or your preferred delimiter] [using strtok()]
Allocate memory to store the integer
Convert the string input to integer [maybe strtol()] and store each integer.
Optionally, you may want to add some validation and error checking.
Read more about fgets() here.
also, don't forget to get rid of the trailing \n stored in the read buffer by fgets()
Recommend using fgets() as suggested by Sourav Ghosh
Otherwise code can search for '\n' before reading each int
#include <ctype.h>
#include <stdio.h>
#define N (20)
int main(void) {
int myarray[N];
int i = 0;
while (1) {
int ch;
while (isspace(ch = fgetc(stdin)) && ch != '\n')
;
if (ch == '\n' || ch == EOF)
break;
ungetc(ch, stdin);
int data;
if (scanf("%d", &data) != 1)
break; // Bad data
if (i < N)
myarray[i++] = data;
}
return 0;
}
My issue is when I try to input spath as the first parameter for fopen(); is keeps looping wether the file exists or not. Yet, when i hard code the parameter to my test file it works properly.I am not sure what the issue is, maybe it is the syntax.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char spath[255], dpath[255];
int c;
FILE *sfp, *dfp;
do
{
printf("Please enter a source file:\n");
fgets(spath, sizeof(spath), stdin);
if(strlen(spath) > 253)
{
while((c = getchar()) != '\n' && c != EOF);
}
}while((sfp=fopen(spath,"r")) == NULL);
}
Upon further reading, fgets() has a new line character in the array which messes things up. To fix this use:
for(i = 0 ; i < lenght ; i++)
{
if(array[i] == '\n')
array[i] = '\0' ;
}
This takes away the new line character and insert a terminator character.
Click this link for further information: Open file with user input (string) - C
Im a beginner learning The C Programming language and using Microsoft visual C++ to write and test code.
Below program in C from text(section 1.5.1) copy its input to its output through putchar() and getchar():
#include <stdio.h>
int main(void)
{ int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;}
The program print characters entered by keyboard every time pressing ENTER.As a result,I can only enter one line before printing. I can't find a way to enter multi-line text by keyboard before printing.
Is there any way and how to let this program input and output multi-line text from keyboard?
Sorry if this is a basic and ignorant question.
Appreciate your attention and thanks in advance.
Some clever use of pointer arithmetic to do what you want:
#include <stdio.h> /* this is for printf and fgets */
#include <string.h> /* this is for strcpy and strlen */
#define SIZE 255 /* using something like SIZE is nicer than just magic numbers */
int main()
{
char input_buffer[SIZE]; /* this will take user input */
char output_buffer[SIZE * 4]; /* as we will be storing multiple lines let's make this big enough */
int offset = 0; /* we will be storing the input at different offsets in the output buffer */
/* NULL is for error checking, if user enters only a new line, input is terminated */
while(fgets(input_buffer, SIZE, stdin) != NULL && input_buffer[0] != '\n')
{
strcpy(output_buffer + offset, input_buffer); /* copy input at offset into output */
offset += strlen(input_buffer); /* advance the offset by the length of the string */
}
printf("%s", output_buffer); /* print our input */
return 0;
}
And this is how I use it:
$ ./a.out
adas
asdasdsa
adsa
adas
asdasdsa
adsa
Everything is parroted back :)
I've used fgets, strcpy and strlen. Do look those up as they are very useful functions (and fgets is the recommended way to take user input).
Here as soon as you type '+' and press enter all the data you entered till then is printed. You can increase the size of array more then 100
#include <stdio.h>
int main(void)
{ int c='\0';
char ch[100];
int i=0;
while (c != EOF){
c = getchar();
ch[i]=c;
i++;
if(c=='+'){
for(int j=0;j<i;j++){
printf("%c",ch[j]);
}
}
}
return 0;
}
You can put a condition on '+' char or whatever character you would like to represent print action so that this character is not stored in the array ( I have not put any such condition on '+' right now)
Use setbuffer() to make stdout fully buffered (up to the size of the buffer).
#include <stdio.h>
#define BUFSIZE 8192
#define LINES 3
char buf[BUFSIZE];
int main(void)
{ int c;
int lines = 0;
setbuffer(stdout, buf, sizeof(buf));
while ((c = getchar()) != EOF) {
lines += (c == '\n');
putchar(c);
if (lines == LINES) {
fflush(stdout);
lines = 0;
}}
return 0;}
Could you use the GetKeyState function to check if the SHIFT key is held down as you press enter? That was you could enter multiple lines by using SHIFT/ENTER and send the whole thing using the plain ENTER key. Something like:
#include <stdio.h>
int main(void)
{ int c;
while (true){
c = getChar();
if (c == EOF && GetKeyState(VK_LSHIFT) {
putchar("\n");
continue;
else if(c == EOF) break;
else {
putchar(c);
}
}