I'm currently working on a program that reads strings from a file and stores them into a 2-D array. However, when I try to print out the contents of the array, I get a random character every time. Here is my code:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
FILE* file_pointer;
char user_input[80];
char line[81];
char all_lines_array[100][81];
int total_lines = 0;
while (1){
printf("Please enter a command: ");
scanf("%s", &user_input);
if (strstr(user_input, "read") != NULL){
file_pointer = fopen("C:\\Users\\Tyler\\Desktop\\Hello.txt","r");
while (fgets(line, 100, file_pointer)) {
line[strlen(line)+1] = "\0";
*all_lines_array[total_lines] = line; //My guess is this is wrong
total_lines++;
}
fclose(file_pointer);
}
}
return 0;
}
I suspect that this is because I'm incorrectly inserting string into my 2-D array, but I have no idea what it is I'm doing wrong. I've set the numbers so that there can only be a maximum of 100 lines in a file, and each line can only be 80 characters long (with the "\0" at the end).
Here is my input file:
John Doe 1221 Washington St. 1234567
Jane Doe 1233 Washington St. 1234568
Cain Doe 1234 Washington St. 1234569
There where some statements flagged when compiling with -Wall [which I always recommend doing], which may have helped with some of the errors.
Here's the corrected version, annotated with comments [please pardon the gratuitous style cleanup]:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main()
{
FILE *file_pointer;
char user_input[80];
char line[81];
char all_lines_array[100][81];
int total_lines = 0;
while (1) {
printf("Please enter a command: ");
// compiler flagged this with a warning
#if 0
scanf("%s", &user_input);
#else
scanf("%s", user_input);
#endif
if (strstr(user_input, "read") != NULL) {
#ifndef CRAIG
file_pointer = fopen("C:\\Users\\Tyler\\Desktop\\Hello.txt", "r");
#else
file_pointer = fopen("input.txt", "r");
#endif
if (file_pointer == NULL) {
printf("file not found\n");
continue;
}
// NOTE: using sizeof here is better as 100 was specified but
// "line" was only 81
while (fgets(line, sizeof(line), file_pointer)) {
// NOTE: I presume this is to strip the newline
// in the original form, it would add garbage chars to the end
// [because of "\0" instead of '\0']
#if 0
line[strlen(line) + 1] = "\0";
#else
line[strlen(line) - 1] = 0;
#endif
// NOTE: the compiler flagged this as well
#if 0
*all_lines_array[total_lines] = line; // My guess is this is wrong
#else
strcpy(all_lines_array[total_lines],line);
#endif
total_lines++;
}
fclose(file_pointer);
}
}
return 0;
}
fgets is reading 100 chars but your static allocated variable char line[81] is only allocates memory for 81 chars.
instead of the = operator use strcpy
Related
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
At the end of this question you will find a piece of code that I am trying to write to read a file called words.txt with the following strings:
uno dos tres cuatro cinco seis siete ocho nueve diez
The aim of the code is to be able to store the strings in a two-dimensional array with dynamic memory allocation. This means it would need to work with any file that has strings.
I would need to check:
Why the code is not working.
How can I make it so that it stores whatever number of words the file has.
Thank you very much guys!
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
int main()
{
char c, *mystring[20];
int i = 0;
FILE *fich;
setlocale(LC_CTYPE,"spanish");
identifica();
fich = fopen("words.txt", "r");
do
{
mystring[i] = malloc (20 * sizeof(char));
fscanf("%s", mystring[i]);
printf ("%s", mystring[i]);
}
while ((c=fgetc(fich))!=EOF);
return 0;
}
You forgot to pass fich to fscanf(). (This is why your code won't work)
Checking if fscanf() is successful should be performed.
You can use realloc() for dynamic re-allocation.
You should increment i for storeing all strings.
Maximum length of string to read should be specified to avoid buffer overrun.
Try this:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
int main()
{
char **mystring = NULL;
int i = 0;
FILE *fich;
setlocale(LC_CTYPE,"spanish");
identifica();
fich = fopen("words.txt", "r");
for (;;)
{
char* next = malloc (20 * sizeof(char));
if (fscanf(fich, "%19s", next) == 1)
{
printf ("%s", next);
mystring = realloc(mystring, sizeof(*mystring) * (i + 1));
mystring[i] = next;
i++;
}
else
{
free(next);
break;
}
}
return 0;
}
While I am aware there are libraries for config file parsing I have tried to write my own implementation. The problem is that I can find the config option but comparing the string before the delimeter failes when I try to compare it with the thing I am searching for. I need to comare it with the thing I am searching for becasue my program allows things like Test2 and Test3 because it cannot check if there are characters before or after the word Test. The compare allways failes and I cannot figure out why.
Here is my code:
Main.c
#include <stdio.h>
#include <stdlib.h>
void Parser(char *CONFIG_FILE, int *P_VALUE, char *STRING_TO_LOOK_FOR);
int main(){
int VALUE;
Parser("config.txt", &VALUE, "Test");
printf("%d \n", VALUE);
}
Parser.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void Parser(char *CONFIG_FILE, int *P_VALUE, char *STRING_TO_LOOK_FOR){
FILE *FP=fopen(CONFIG_FILE,"a+");
char TMP[256]={0x0};
int i = 1;
while(FP!=NULL && fgets(TMP, sizeof(TMP), FP)!=NULL){ //Loop through every line
i=i+1; //Increment the line number
if (strstr(TMP, STRING_TO_LOOK_FOR)){ //Is the term im looking for in this line
char *NAME_OF_CONFIG_STR = strtok(TMP, "= "); //look for delimiter
char *STRVALUE = strtok(NULL, "= "); //Get everything past the delimiter
char *P_PTR;
char *pos;
if ((pos=strchr(NAME_OF_CONFIG_STR, '\n')) != NULL){ //attempt remove \n doesn't work
*pos = '\0';
}
if(strcmp(STRING_TO_LOOK_FOR, NAME_OF_CONFIG_STR) == 0){ //try to check the two are the same
*P_VALUE = strtol(STRVALUE, &P_PTR, 10); //Returns an integer to main of the value
}
}
}
if(FP != NULL){
fclose(FP);
}
}
config.txt:
Test= 1234
Test2= 5678
Test3= 9012
Thanks to BLUEPIXY and the demo they created this problem has been solved. The issue was in the gcc comiler options I had forgotten -std=99 somehow this caused the program to behave correctly.
I'm a student, I am wondering...
How can I make a program that can Get some data from my text file to a variable on my program and print them
Example:
My Text File
I,Ate,Cookies
She,Drink,Coffee
Tom,Wears,Pyjamas
My code
main()
{
FILE *fp=fileopen("c:\\textfile.txt","r");
char name[20],action[20],item[20];
prinf("Enter name: \n");
scanf("%s",&name);
/* I dont Know what to do next */
}
I though about some checking code:
if (name==nametxt) /*nametxt is the first line on the text file */
{
printf("%s\n %s\n %s\n",name,action,item);
}
If the name is "I",the output would look like this :
Enter name:
I
I
Eat
Cookies
A help will satisfy my curiosity thanks in advance
You are reading characters from file until you receive new line character (\n) or fill an array, then you return characters stored in an array passed by caller.
From this returned array you may get separated values with strtok.
Repeat until you receive 0 from getline (Getline received EOF from file.)
Here is simple example with your own getline function which you may modify.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int getline(char s[],int lim, FILE * fp)
{
int c, i;
for (i=0; i < lim-1 && (c=fgetc(fp))!=EOF && c!='\n'; ++i)
{
s[i] = c;
}
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int main()
{
FILE * fp = fopen("c:\\textfile.txt", "r");
char line[100];
char * ptr;
while (getline(line, 100, fp))
{
ptr = strtok(line, ",");
while( ptr != NULL )
{
printf(" %s\n", ptr);
ptr = strtok(NULL, ",");
}
}
return 0;
}
Output
I
Ate
Cookies
She
Drink
Coffee
Tom
Wears
Pyjamas
Storing strings into variable isnt tough, here is an example
strcpy(name, ptr);
But be careful, writing outside of bounds have undefined behavior.
strncpy(name, ptr, 100); You can limit number of copied characters with strncpy, but be careful, this function is error-prone.
You can do like this,
Go on reading characters from a file, after every character is read compare with ',' character.
If the character read is ',' then you have finished reading the name, otherwise store it in a character array and continue reading the file.
Once you hit ',' character, terminate the character array with null character(Now you have a complete name with you).
Compare this character array with a string you receive as input using a strcmp(String compare function). If its it matches decide what you wanna do?
I hope i am clear.
There is different ways to read data from a FILE * in C :
You read only one character : int fgetc(FILE *fp);.
You read a whole line : char *fgets(char *buf, int n, FILE *fp); (take care to buf, it must point to allocate memory).
You read a formatted string, which is your case here : int fscanf(FILE *stream, const char *format, ...), it works like printf() :
This way :
char name[20], action[20], item[20];
FILE *f = fopen("myfile.txt", "r");
if (! f)
return;
if (3 == fscanf(f, "%19[^,\n],%19[^,\n],%19[^,\n]\n", name, action, item))
printf("%s %s %s\n", name, action, item)
%30[^,\n], here is used to read of whole object of your line, except , or \n, which will read item by item the content of your string.
start with like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DATA_FILE "data.txt"
#define LEN 19
#define SIZE (LEN+1)
//Stringification
#define S_(n) #n
#define S(n) S_(n)
enum { NOT_FOUND, FIND };
int pull_data(const char name[SIZE], char action[SIZE], char item[SIZE]){
int ret = NOT_FOUND;
FILE *fp = fopen(DATA_FILE, "r");//fileopen --> fopen
if(fp == NULL){
perror("fopen:");
exit(EXIT_FAILURE);
} else {
char nametxt[SIZE];
*action = *item = 0;
while(fscanf(fp, "%" S(LEN) "[^,],%" S(LEN) "[^,],%" S(LEN) "[^\n]%*c", //"%19[^,],%19[^,],%19[^\n]%*c"
nametxt, action, item) == 3){
if(strcmp(name, nametxt) == 0){//Use strcmp for comparison of strings
ret = FIND;
break;
}
}
}
fclose(fp);
return ret;
}
int main(void){
char name[SIZE], action[SIZE], item[SIZE];
printf("Enter name: \n");//prinf --> printf
if(scanf("%" S(LEN) "s", name) == 1){
if(pull_data(name, action, item) == FIND){
printf("%s\n%s\n%s\n", name, action, item);
} else {
printf("%s not found.\n", name);
}
}
}
Write a program that will read standard input and echo each line to standard output with a line number and tab preceding it. When you run this program and enter lines from the terminal, lines of input will be interspersed with lines of output. If your system has output redirection and you redirect output to a file, the file will look like the input with the lines numbered.
Here is an example of how the script should work.
User input in bold.
Enter your text:
This is line 1.
1 This is line 1.
This is line 2.
2 This is line 2.
This is the last line of input.
3 This is the last line of input.
The last line will end the process.
Here is what I have so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Enter your text: \n");
while (1)
{
int ch = getc(stdin);
fflush(stdout);
if(ch == EOF) break;
putc(ch, stdout);
}
return 0;
}
I have been attempting at this for a few hours now to no luck, any help is appreciated. I basically cant get my script to display the example output. I can get my script to display the stdin as an stdout and thats all. This is a C assignment.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(void){
size_t no = 0;
bool line_top = true;
printf("Enter your text: \n");
while (1) {
int ch = fgetc(stdin);
if(ch == EOF) break;
if(line_top)
printf("%zu ", ++no);
line_top = (ch == '\n');
fputc(ch, stdout);
}
fflush(stdout);
return 0;
}
To properly complete the assignment, you need to understand what is the line. The code you have in place reads and prints data symbol-by-symbol. This is not going to print the numbers requested!
There are two solutions here. First is to switch from reading symbol by symbol to line by line, and than print an ever incrementing counter every time you print a line. Second is leave reading symbol-by-symbol, but print an incremented number every time you've read a new line symbol from the input. A slight challenge here is that you would need a state - that is, once you've seen the new line character, you should remember that fact, but not print the number right away - this might be the last line in the input. Instead, print a number whenever your saved state tells you so, and reset the flag after this.
A separate question is what to do with the empty lines - do they participate in counter increment or not - but this is probably beyond the assignment.
Ok you should only do what the assignment requires. Here's the most straight-forward solution I can think of:
#include <stdio.h>
int main(void)
{
char buf[1024];
int num = 0;
/* read a line as long as we can read (no error / EOF) */
while (fgets(buf, 1024, stdin))
{
/* print line number */
printf("%d\t", ++num);
/* print what we actually read */
fputs(buf, stdout);
}
return 0;
}
Test run:
> ./numlines < numlines.c
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char buf[1024];
6 int num = 0;
7
8 /* read a line as long as we can read (no error / EOF) */
9 while (fgets(buf, 1024, stdin))
10 {
11 /* print line number */
12 printf("%d\t", ++num);
13
14 /* print what we actually read */
15 fputs(buf, stdout);
16 }
17
18 return 0;
19 }
20
Code needs to keep track of the beginning of a line. This can be done by reading a line using fgets() or by looking at individual char.
fgets() is likely faster, but it limits line length to some constant.
fgetc() gets 1 unsigned char at a time (or EOF).
The below follows OP's lead, yet adds the inner while loop.
Not much code needed.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned long long line_number = 0;
int ch;
while ((ch = fgetc(stdin)) != EOF) {
printf("%llu\t", ++line_number);
while (ch != EOF && fputc(ch, stdout) != '\n') {
ch = fgetc(stdin);
}
}
return 0;
}
const int buflen = 1024;
char buffer[buflen];
int count = 0;
while (1)
{
char* line = fgets(buffer, buflen, stdin);
if (line == null)
break;
fprintf(stdout, "%d: %s\n", ++count, line);
}
Here's a c++ solution using getline and cout.
#include <string>
#include <iostream>
using namespace std;
int main()
{
unsigned int i=0;
string s;
cout<<"Enter your text: "<<endl;
while (std::getline(cin,s))
{
cout<<++i<<'\t'<<s<<endl;
}
return 0;
}
Here a c solution:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int exit=0, i=0, newline=1;
printf("Enter your text: \n");
while (!exit)
{
int ch = getc(stdin);
if(newline){
printf("\n%d\t",++i);
newline=0;
}
switch(ch){
case '\n':
newline=1;
printf("\n");
break;
case EOF:
printf("\n");
exit=1;
break;
default:
printf("%c",(char)ch);
break;
}
}
return 0;
}
#include<stdio.h>
int main()
{
char line[1000];
int lineno=0;
while((fgets(line,1000, stdin)) != NULL)
{
lineno++;
printf("%d ",lineno);
fputs(line, stdout);
}
}
It will work as you are expected. It is a simple method to do this. You don't have to put the while(1) and if condition and break the loop.