Here's my task and below you can find my specific question and the code I wrote:
Write a program that reads strings and writes them to a file. The string must be dynamically
allocated and the string can be of arbitrary length. When the string has been read it is written to the
file. The length of the string must be written first then a colon (‘:’) and then the string. The program
stops when user enters a single dot (‘.’) on the line.
For example:
User enters: This is a test
Program writes to file: 14:This is a test
Question:
My code adds the number of characters and the colon, but not the string I typed, and when entered "." it wont exit
This is the code I have so far:
#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_SZ 256
int main() {
char key[] = ".";
char *text;
int i;
text = (char*)malloc(MAX_NAME_SZ);
FILE* fp;
do {
printf("Enter text or '.' to exit: ", text);
fgets(text, MAX_NAME_SZ, stdin);
for (i = 0; text[i] != '\0'; ++i);
printf("%d: %s", i);
fp = fopen("EX13.txt", "w");
while ((text = getchar()) != EOF) {
putc(text, fp);
}
fclose(fp);
printf("%s\n", text);
} while (strncmp(key, text, 1) != 0);
puts("Exit program");
free(text);
return 0;
}
There are many issues in your code, almost everything is wrong.
Just a few problems:
You use printf("%d: %s", i); to print on the screen what should go into the file.
The loop while ((text = getchar()) != EOF) doesn't make any sense.
You're closing the file after the first line entered
You ignore all compiler warnings
The end condition while (strncmp(key, text, 1) != 0) is wrong, you're only testing if the string starts with a ., and you're testing it too late.
This could be a start:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_SZ 256
int main() {
char* text;
int i;
text = (char*)malloc(MAX_NAME_SZ);
FILE* fp;
fp = fopen("EX13.txt", "w");
if (fp == NULL)
{
printf("Can't open file\n");
exit(1);
}
do {
printf("Enter text or '.' to exit: ");
fgets(text, MAX_NAME_SZ, stdin);
if (strcmp(".\n", text) == 0)
break;
for (i = 0; text[i] != '\0' && text[i] != '\n'; ++i);
fprintf(fp, "%d: %s", i, text);
} while (1);
fclose(fp);
puts("Exit program");
free(text);
return 0;
}
There is a limitation though, in this program the maximum line length is 254 characters, not including the newline character. As far as I understood, the line length must be arbitrary.
I let you do this on your own as an exercise, but at your C knowledge level it will be hard.
I think this should work for strings that are shorter than 255 chars.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_SZ 256
int main()
{
char key[] = ".\n";
char *text;
text = (char*)malloc(MAX_NAME_SZ);
if (text == NULL)
{
perror("problem with allocating memory with malloc for *text");
return 1;
}
FILE *fp;
fp = fopen("EX13.txt", "w");
if (fp == NULL)
{
perror("EX13.txt not opened.\n");
return 1;
}
printf("Enter text or '.' to exit: ");
while (fgets(text, MAX_NAME_SZ, stdin) && strcmp(key, text))
{
fprintf(fp, "%ld: %s", strlen(text) - 1, text);
printf("Enter text or '.' to exit: ");
}
free((void *) text);
fclose(fp);
puts("Exit program");
return 0;
}
Related
I'm trying to copy words from one file to another, but the words must begin with the given letter. It's working but doesn't copy every word that matches.
#include <stdio.h>
int main() {
FILE *f = fopen("words.txt", "r");
FILE *f2 = fopen("words_copy.txt", "a+");
char usr;
printf("enter letter: ");
scanf("%c", &usr);
char buffer[255];
char ch, ch2;
while ((ch = fgetc(f)) != EOF) {
ch2 = fgetc(f);
if (ch2 == usr && ch == '\n') {
fputc(ch2, f2);
fgets(buffer, sizeof(buffer), f);
fputs(buffer, f2);
}
}
return 0;
}
Words.txt contains:
adorable aesthetic alluring angelic appealing arresting attractive
blooming charismatic charming cherubic chocolate-box classy contagious
cute dazzling debonair decorative delectable delicate distinguished
enchanting enticing eye-catching glamorous glossy good-looking
gorgeous infectious lovely lush magnetic magnificent majestic melting
mesmerizing noble picturesque poetic prepossessing shimmering striking
stunning winsome
every word is in next line,
when I'm running the program and giving the letter m words_copy.txt contains only:
magnificent melting
How to fix to copy every word with matching letter?
The test in the loop is incorrect: you check the first letter after a newline and output the line if there is a match. With this logic:
you cannot match the first word in the file
you only match words starting with usr
and the word following a match is ignored
Furthermore, you ch and ch2 should be defined with type int to match EOF reliably, you should test for fopen failure and close the files after use.
You should use a simpler approach:
read a word
test if it contains the letter
output the word if it matches
Here is a modified version:
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char usr;
char buffer[256];
int ch = 0;
size_t pos;
FILE *f = fopen("words.txt", "r");
if (f == NULL) {
fprintf(stderr, "cannot open words.txt: %s\n", strerror(errno));
return 1;
}
FILE *f2 = fopen("words_copy.txt", "a+");
if (f2 == NULL) {
fprintf(stderr, "cannot open words_copy.txt: %s\n", strerror(errno));
fclose(f);
return 1;
}
printf("enter letter: ");
if (scanf(" %c", &usr) != 1) {
fprintf(stderr, "missing input\n");
fclose(f);
fclose(f2);
return 1;
}
while (ch != EOF) {
pos = 0;
/* read a word, stop at whitespace and end of file */
while ((ch = fgetc(f)) != EOF && !isspace(ch)) {
if (pos + 1 < sizeof(buffer))
buffer[pos++] = (char)ch;
}
buffer[pos] = '\0';
/* test for a match */
if (strchr(buffer, usr)) {
/* output matching word */
fprintf(f2, "%s\n", buffer);
}
}
fclose(f);
fclose(f2);
return 0;
}
This question already has answers here:
How should character arrays be used as strings?
(4 answers)
Closed 12 months ago.
I have a file with an unknown number of strings and each of these strings is of an unknown length.
I would like to make each line of the file its own string in an array of strings.
I tried to use dynamic allocation in a char** array, but I don't think I'm approaching this correctly.
Below is the code I have tried. It's getting stuck in an infinite loop, and I can't figure out why.
(The text file I'm reading from ends with a line break, by the way.)
#include <getopt.h> //for getopts
#include <sys/stat.h> //to do file stat
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h> //user macros
#include <stdlib.h>
#include <stdbool.h>
#include <libgen.h>
#include <errno.h>
int main(int argc, char *argv[]) {
//storing the filename inside string
char* filename = argv[1];
FILE *fp1 = fopen(filename, "r");
if (fp1 == NULL) {
fprintf(stderr, "Error: Cannot open '%s'. No such file or directory.\n", filename);
return EXIT_FAILURE;
}
/**
* we begin by getting the number of numbers in the file
* the number of numbers = number of lines = number of line breaks
*/
size_t numNumbers = 0;
// while((fscanf(fp1, "%*[^\n]"), fscanf(fp1, "%*c")) != EOF){
// numNumbers = numNumbers + 1;
// }
char c;
while((c = fgetc(fp1)) != EOF){
if(c == '\n'){
numNumbers++;
}
}
fclose(fp1);
FILE *fp2 = fopen(filename, "r");
char** arrayOfStrings = malloc(numNumbers * sizeof(char*));
for(int i = 0; i < numNumbers; i++) {
int len = 0;
if(((c = fgetc(fp1)) != '\n') && (c != EOF)){
len++;
}
arrayOfStrings[i] = malloc(len * sizeof(char));
}
printf("hello1\n");
//for(int i = 0; i < numNumbers; i++){
// fscanf(fp2, "%s", (arrayOfStrings[i]));
//}
fclose(fp2);
// for(int i = 0; i < numNumbers; i++){
// fprintf(stdout, "%s", arrayOfStrings[i]);
// }
return 0;
}
(I'm very new to C, so please go easy on me!)
In C, strings are terminated with a '0' byte, so it looks like your malloc for each string is 1 character too short -- you've only allowed space for the text.
In addition, you mean the count for the size of each line to be a while loop, not an if statement - right now you are counting each line as length "1".
Finally, you are reading off the end of the file in your commented out fscanf code because you haven't closed and reopened it.
Assuming you want to split the input to the strings by the newline character, would you please try:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char *filename; // filename to read
char **arrayOfStrings = NULL; // array of strings
char line[BUFSIZ]; // line buffer while reading
char *p; // temporal pointer to the input line
int i, num; // counter for lines
FILE *fp; // file pointer to read
if (argc != 2) {
fprintf(stderr, "usage: %s file.txt\n", argv[0]);
return EXIT_FAILURE;
}
filename = argv[1];
if (NULL == (fp = fopen(filename, "r"))) {
perror(filename);
return EXIT_FAILURE;
}
// read the input file line by line
while (fgets(line, BUFSIZ, fp)) {
if ((p = strrchr(line, '\n'))) *p = '\0'; // remove trailing newline, if any
if ((p = strrchr(line, '\r'))) *p = '\0'; // remove trailing cr character, if any
if (NULL == (arrayOfStrings = realloc(arrayOfStrings, (num + 1) * sizeof(char **)))) {
// enlarge the array according to the line count
perror("realloc");
return EXIT_FAILURE;
}
if (NULL == (arrayOfStrings[num] = malloc(strlen(line) + 1))) {
// memory for the string of the line
perror("malloc");
return EXIT_FAILURE;
}
strcpy(arrayOfStrings[num], line);
num++;
}
// print the strings in the array
for (i = 0; i < num; i++) {
printf("%d %s\n", i, arrayOfStrings[i]);
}
fclose(fp);
return 0;
}
If the input file looks something like:
This
is
the
input.
Then the output will be:
0 This
1 is
2 the
3 input.
I have written a small program to read in a series of strings from a file and then to store them in a 2D Arrray. The strings are read into the array correctly, yet my program is not countering the number of rows in the file like I had expected.
I am honestly at a loss and cannot figure out why the program is not counting the rows in the file. Any explanation as to what I am doing wrong is greatly appreciated.
Here is the code that I have so far:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
FILE* fp;
char nameArray[20][120], str[20];
int i = 0, j = 0, n;
int count = 0;
char name[20]; //filename
int ch;
printf("Please enter a file name: ");
scanf("%s", &name);
fp = fopen(name, "r");
if (fp == NULL) {
printf("File \"%s\" does not exist!\n", name);
return -1;
}
while (fscanf(fp, "%s", str) != EOF)
{
strcpy(nameArray[i], str);
i++;
}
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n')
count++;
}
for (i = 0; i<=count; i++)
{
printf("%s", nameArray[i]);
}
fclose(fp);
return 0;
}
I have written a C program that opens a text file and compares the given string with the string present in the file. I'm trying to print the line number in which the same string occurs, but I am unable to get the proper output: output does not print the correct line number.
I would appreciate any help anyone can offer, Thank you!
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
int num = 0, line_number = 1;
char string[50];
char student[100] = { 0 }, chr;
while (student[0] != '0') {
FILE *in_file = fopen("student.txt", "r");
if (in_file == NULL) {
printf("Error file missing\n");
exit(1);
}
printf("please enter a word \n");
scanf("%s", student);
while (fscanf(in_file, "%s", string) == 1) {
if (chr == '\n') {
if (strstr(string, student) == 0) {
break;
} else
line_number += 1;
}
}
printf("line number is: %d\n", line_number);
fclose(in_file);
}
return 0;
}
You cannot read lines with while (fscanf(in_file, "%s", string), the newlines will be consumed by fscanf() preventing you from counting them.
Here is an alternative using fgets():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char string[200];
char student[100];
int num = 0, line_number = 1;
FILE *in_file = fopen("student.txt", "r");
if (in_file == NULL) {
printf("Error file missing\n");
exit(1);
}
printf("please enter a word \n");
if (scanf("%s", student) != 1) {
printf("No input\n");
exit(1);
}
while (fgets(string, sizeof string, in_file)) {
if (strstr(string, student)) {
printf("line number is: %d\n", line_number);
}
if (strchr(string, '\n')) {
line_number += 1;
}
fclose(in_file);
}
return 0;
}
This program attempts to save the contents of a text file into a character variable array. It is then supposed to use my_getline() to print the contents of the character array. I've tested and see that the contents are in fact getting saved into char *text but I can't figure out how to print the contents of char *text using my_getline(). my_getline is a function we wrote in class that I need to use in this program. When I attempt to call it in the way that was taught, it 1 is printed to terminal but then the terminal just waits and nothing else is printed. Any guidance would be appreciated. Also, let me know if I'm missing any information that would help.
/* Include the standard input/output and string libraries */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Define the maximum lines allowed in an input text and NEWLINE for getline funct. */
#define MAXPATTERN 15
#define MAXFILENAMELENGTH 15
#define NEWLINE '\n'
/* function prototypes */
void my_getline(char text[]);
int find_string(char text[], char pattern[], int length_text, int length_pattern);
int main()
{
FILE *fp;
long lSize;
char *text;
char fileName[MAXFILENAMELENGTH], pattern[MAXPATTERN];
char c;
int length_text, length_pattern, j, lineNumber = 1;
printf("Enter file name: ");
scanf("%s", fileName);
fp = fopen(fileName, "r");
if (fp == NULL)
{
printf("fopen failed.\n");
return(-1);
}
fseek(fp, 0L, SEEK_END);
lSize = ftell(fp);
rewind(fp);
/* allocate memory for all of text file */
text = calloc(1, lSize + 2);
if(!text)
{
fclose(fp);
fputs("memory allocs fails", stderr);
exit(1);
}
/* copy the file into text */
if(1 != fread(text, lSize, 1, fp))
{
fclose(fp);
free(text);
fputs("Entire read fails", stderr);
exit(1);
}
text[lSize + 1] = '\0';
printf("%s has been copied.\n", fileName);
rewind(fp);
printf("%d ", lineNumber);
for (j = 0; (j = getchar()) != '\0'; j++)
{
my_getline(text);
printf("%d %s\n", j+1, text);
}
printf("Enter the pattern you would like to search for: ");
scanf("%s", pattern);
printf("\nYou have chosen to search for: %s\n", pattern);
fclose(fp);
free(text);
return(0);
}
void my_getline(char text[])
{
int i = 0;
while ((text[i] = getchar()) != NEWLINE)
++i;
text[i] = '\0';
}
Your function is causing a system hang because you're calling getchar(), which returns the next character from the standard input. Is this really what you want?
At this point, your program is expecting input from the user. Try typing in the console windows and pressing to see it coming back from the "hang"
It is most likely causing an infinite loop because you are not checking whether you have reached EOF.
void my_getline(char text[])
{
int i = 0;
int c;
while ( (c = getchar()) != NEWLINE && c != EOF )
text[i++] = c;
text[i] = '\0';
}