How to store STDIN from text file - c

I need to read in words from a text file and then count the occurrences of each word but I can't figure out how to store the words in a variable.
I read the code in using fgets, and then i can print it using printf. However when I try to store the character array in a different array that I can use to compare the character arrays later, i keep getting seg faults. How can I go about saving the character array "line" in a different array?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 500
#define MAXWORDS 1000
int main ( int argc, char *argv[] ) {
char line[MAXSIZE];
char line1[MAXWORDS][MAXSIZE];
int i,j,k;
int count = 0;
while ( fgets ( line, MAXSIZE, stdin ) != NULL ) {
printf("%s", line);
strcpy(line1[count], line);
printf("%s\n", line1[count][i]);
count++;
}
return(0);
}
(This is my updated code, it still prints the first line and then seg faults.)
when I compile and run this code, it prints the first line of the text file and then returns "segmentation fault"

Perhaps the question code is close.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 500
#define MAXWORDS 1000
int main(int argc, char *argv[])
{
char line[MAXSIZE];
char line1[MAXWORDS][MAXSIZE];
int count = 0;
while(fgets(line, MAXSIZE, stdin))
{
printf("%s", line);
strcpy(line1[count], line);
printf("%s\n", line1[count]); // instead of: printf("%s\n", line1[count][i]);
count++;
}
return(0);
}

Your strcpy works as it should, but the printf caused a warning already at compile time, change the printf-line from printf("%s\n", line1[count]); to printf("%s\n", line1[count]);
After the while loop you can verify your copy with:
for (int i=0; i < count; i++){
printf("%d: %s",i, line[i]);
}
Although fgets will put a terminating 0-byte at the end of the buffer, it would be more defensive to user strncpy which is guaranteed not copy more than n-bytes, but in this example you could eliminate the copy altogether by writing directly in to line[count] buffer.
Also you shod take care and stop reading before overwriting your buffers.
When you call fgets you limit the read to MAXSIZE which is good but you should also check count is below MAXWORDS

Related

Problem scanning a string from a text file into an array

Let's say I have a simple words.txt file that has contents like this:
house
car
horse
So I want to scan those words into an array so it would be words[0] would be house, words[1] would be car etc.. So I am having this problem that it seems I am having an infinite while loop, why is that? And am I scanning the words properly?
#include <stdio.h>
#include <stdlib.h>
#define MAX_WORDS 10
int main() {
FILE *f;
f = fopen("words.txt", "r");
char words[MAX_WORDS];
int i = 0;
while(1) {
fscanf(f, "%s", &words[i]);
if(feof(f)) {
break;
}
i++;
}
fclose(f);
return 0;
}
Your array can hold 1 word or n series of characters. What you want is an array of strings. First dimension must have MAX_WORD size and 2nd MAX_WORD_LEN size.
#include <stdio.h>
#include <stdlib.h>
#define MAX_WORDS 10
#define MAX_LEN 51
int main() {
FILE *f;
f = fopen("words.txt", "r");
char words[MAX_WORDS][MAX_LEN]; /* Can hold MAX_WORDS string of MAX_LEN chars */
int i = 0;
while(1) {
fscanf(f, "%50s", words[i]);
if(feof(f) || i == MAX_WORDS - 1) {
break;
}
i++;
}
fclose(f);
return 0;
}
First, you should think about the array storing the strings. Remember that strings are arrays by them selves. When you know the maximal length of the words it is easy to define this array of char arrays:
#define MAX_WORD_LEN 32
char words[MAX_WORDS][MAX_WORD_LEN];
Then you can read each string like this
fscanf(f, "%s", words[i]);
Note: your code can lead to buffer overflows, because you do not have a check for the variable i and "%s" is considered insecure (like gets), because it assumes that the read string fits into the buffer. Do not use these if possible, otherwise use these only, when you trust the input: Never: scanf("%s", ...); or gets(...)
If you know the width, you can use it with scanf as the following:
char str[11];
scanf("%10s", str); // one less than the buffer size

How to read & output an input with spaces and newlines

I am attempting to scanf a multiline input in C and output it. However, I'm having trouble handling spaces and newline characters. If the input is:
Hello.
My name is John.
Pleased to meet you!
I want to output all three lines. But my output ends up being just:
Hello.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char s[100];
scanf("%[^\n]%*c", &s);
printf(s);
return 0;
}
Its much easier to use fgets():
#include <stdio.h>
int main(void)
{
char buffer[1000];
while (fgets(buffer, sizeof(buffer), stdin) && buffer[0] != '\n') {
printf("%s", buffer);
}
}
An empty line (first character is newline) ends input.
If you have to read all input first before printing the result, things get a little bit more complicated:
#include <stddef.h> // size_t
#include <stdlib.h> // EXIT_FAILURE, realloc(), free()
#include <stdio.h> // fgets(), puts()
#include <string.h> // strlen(), strcpy()
int main(void)
{
char buffer[1000];
char *text = NULL; // pointer to memory that will contain the whole text
size_t total_length = 0; // keep track of where to copy our buffer to
while (fgets(buffer, sizeof(buffer), stdin) && buffer[0] != '\n') {
size_t length = strlen(buffer); // remember so we don't have to call
// strlen() twice.
// (re)allocate memory to copy the buffer to:
char *new_text = realloc(text, total_length + length + 1); // + 1 for the
if (!new_text) { // if (re)allocation failed terminating '\0'
free(text); // clean up our mess
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
text = new_text; // now its safe to discard the old pointer
strcpy(text + total_length, buffer); // strcpy instead of strcat so we don't
total_length += length; // have to care about uninitialized memory
} // on the first pass *)
puts(text); // print all of it
free(text); // never forget
}
*) and it is also more efficient since strcat() would have to find the end of text before appending the new string. Information we already have.

I want to break a string stored in an array at the '\n' character?

My file contains three lines, after using fgets to read the file into an array, I want to break the three lines at the new line character and print the three lines separately out on the console and if possible store the three lines in three different arrays.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
FILE *infile;
char data[BUFSIZ],*pa,token_seperator[]={"\n"};
infile=fopen("example","r");
while((fgets(data,BUFSIZ,infile)!=NULL))
pa=strtok(data,token_seperator);
while(pa!=NULL)
{
printf("%s\n",pa);
pa=strtok(NULL,token_seperator);
}
}
There is no any sense "to break the three lines at the new line character" because a line can contain no more than one new line character.
If you need to read each line in a separate array then just declare a two-dimensional character array. If you want you can remove the new line character appended to each line by the call of fgets.
So the program can look the following way.
#include <stdio.h>
#include <string.h>
#define N 3
int main( void )
{
FILE *infile;
char data[N][BUFSIZ];
infile = fopen( "example", "r" );
if ( infile )
{
size_t n = 0;
for (; n < N && fgets(data[n], BUFSIZ, infile); n++)
{
data[n][strcspn(data[n], "\n")] = '\0';
}
for (size_t i = 0; i < n; i++)
{
printf("%s\n", data[i]);
}
}
return 0;
}
The function below,truncCrLf, deletes from ASCII-0 strings the first occurence of the CR and/or LF codes. This is what you are looking for because the fgets function reads from the file till these ASCII codes (0xA and/or 0xD).
This function acts under both Linux and Windows SO.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * truncCrLf(char *data)
{
char *app=NULL;
app = strchr(data, '\n');
if (app)
*app=0;
app = strchr(data, '\r');
if (app)
*app=0;
return data;
}
int main(void)
{
char test[200];
strcpy(test,"Hello world\n");
printf("%s......\n",test);
truncCrLf(test);
printf("%s......\n",test);
return 0;
}
You will need allocate some memory to do this, just because you don't know how many line you finally will have nor the size of each one.
I suggest you the next code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef SplittedString char[BUFSIZ]
int main()
{
FILE *infile;
char token_seperator[]={"\n"};
SplittedString data;
SplittedString myLines[50]; // you can modify this number to hold more lines
int i=0;
infile=fopen("example","r");
while((fgets(data,BUFSIZ,infile)!=NULL) && i < 50){ //prevent array overflow
printf("%s\n",data);
strcpy(myLines[i], data);
++i;
}
}

fgets segmentation fault when reading input from user

here's the offending code using ubuntu
char *name;
int main(void)
{
fgets(name, sizeof(name), stdin);
}
void HUD()
{
printf("%s ", name);
}
Here's my problem. I started with scanf("%s", &name) and was getting junk at the end of the string. Through the last 2 hours have been reading docs on scanf, and fgets, because apparently scanf shouldn't be used when you don't know the size of the array you want, (and since user input can vary in size) I decided to try using fgets. I've also tried setting a fixed value both by char name[100]; and by fgets(name, 100, stdin)
Now I'm getting a segmentation fault, and through reading every result I found on the first 2 pages of google, my syntax appears correct, and I've found nothing on cboard or here to fix my problem.
Any ideas?
sizeof(name) Will be the size of the pointer on your system, on mine it's 8 bytes. Not the size of the buffer, as you might have been expecting
Also char* name is uninitialised. You will try to write to an uninitialised buffer and it will end in undefined behaviour.
To resolve either make it a fixed size buffer or allocate some space on the heap.
Allocate
#include <stdio.h>
#include <stdlib.h>
#define NAME_SIZE 100
char *name;
void HUD()
{
printf("%s ", name);
}
int main(void)
{
name=calloc(NAME_SIZE, sizeof(char));
fgets(name, NAME_SIZE, stdin);
HUD();
free(name);
}
Static Array
#include <stdio.h>
#include <stdlib.h>
#define NAME_SIZE 100
char name[NAME_SIZE];
void HUD()
{
printf("%s ", name);
}
int main(void)
{
fgets(name, NAME_SIZE, stdin);
HUD();
}
You must pass the size of the buffer to fgets so it know how much space it has to write in to.
char *fgets(char *restrict s, int n, FILE *restrict stream);
The fgets() function shall read bytes from stream into the array
pointed to by s, until n-1 bytes are read, or a is read and
transferred to s, or an end-of-file condition is encountered. The
string is then terminated with a null byte. [0]
You need to allocate it to a specific size and call fgets with that size. This code can help you accomplish the same thing, but it has a fixed size buffer.
#include <stdlib.h>
#include <stdio.h>
char name;
char* buffer;
int buffer_size = 16;
int i = 0;
void HUD()
{
printf("%s ", buffer);
}
int main(void)
{
buffer = malloc(buffer_size);
if(!buffer) return;
for(;;) {
name = getchar();
if(name < 0) {
buffer[i] = '\0';
goto finish;
} else if(i < (buffer_size -1)) {
buffer[i++] = name;
} else if(name == '\n') {
break;
}
}
buffer[i] = '\0';
finish:
HUD();
free(buffer);
return 0;
}
[0] http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html

c - how can I print specified count of a char in a line

I want to print a line similar as following:
====================================
And I need to control the count of the char, and able to specify which char to print.
I don't want to use loop.
Is it possible to do this with a single printf() statement?
#Update
I ask this because I use printf in this way sometimes:
printf("%10s\n", "abc");
So, if printf could do this, then it's possible to do what I ask, I am just not sure ... now I know it can't ...
Ok, I wrote a simple util function to do this:
#include <stdio.h>
void printRepeatChar(char c, int count) {
char cs[count+1];
int i;
for(i=0; i<count; i++)
cs[i] = c;
cs[count] = '\0';
printf("%s\n", cs);
}
int main(int argc, char * argv[]) {
printRepeatChar('-', 6*4);
}
maybe use memset() from string.h instead of the direct loop makes the code shorter, just as in the answers.
And, thank you all for help.
#include <stdio.h>
#include <string.h>
void PrintStuff( char to_print, int length ) {
// adjust buffer size as desired
char buffer[256];
// -1 for null terminator
if( length > sizeof(buffer)-1 ) length = sizeof(buffer)-1;
// fill buffer with desired character
memset( buffer, to_print, length );
// add null terminator
buffer[length] = 0;
// print to output
puts( buffer );
}
int main() {
PrintStuff( '=', 11 );
return 0;
}
http://ideone.com/RjPr83
And to answer the subquestion: no, printf cannot repeat a character as a formatting rule. It can only repeat spaces or 0's when padding.
#include <stdio.h>
#include <string.h>
int main(void) {
char c='=';
char a[20];
memset(a,c,(sizeof(a)-1));
a[19] = '\0';
printf("%s\n",a);
return 0;
}
Dynamic memory allocation and character scanning can be added to this .

Resources