How to choose different words to be shown using if statement? - c

Whenever I make ch[index]==0, it gives me first word from text file but whenever I select ch[index]==1, it gives me nothing. How to make this if statement working?
#include <stdio.h>
#include<stdlib.h>
int main(){
FILE * fr = fopen("/home/bilal/Documents/file.txt","r");
char ch[100];
int index = 0;
if(fr != NULL){
while((ch[index] = fgetc(fr)) != EOF){
if(index[ch]==1){ // here is if statement
if(ch[index] == ' ') {
ch[index] = '\0';
printf("Here is your %s: \n",ch);
index = 0;
}
else { index++; }
}
}
fclose(fr);
}
else{ printf("Unable to read file."); }
return 0;
}

For a start you have an fclose(fr) inside your i loop, but then you never open the file again. You are also incrementing i inside the loop a second time, which is never good in practice.
try this:
for (int i=0; i<8; i++){
fr = fopen("/home/bilal/Documents/file.txt","r");
index = 0;
if(fr != NULL){
and remove the fopen from the top.
There is probably a better way than opening and closing the file on each loop iteration.

Here is a code that should work and show the second word, although I didn't test it:
#include <stdio.h>
//#include <stdlib.h> //not needed
int main(void)
{
FILE* fr = fopen("/home/bilal/Documents/file.txt", "r");
char ch[100];
int index = 0, c, i = 0;
//for loop is useless
if (fr == NULL)
{
printf("Unable to read file.");
return 0;
//I prefer error checking without a giant if statement, but it's up to you
}
c = fgetc(fr); //fgetc() returns an int, not char
while (c != EOF)
{
ch[index] = c;
if (ch[index] == ' ')
{
if (i == 1)
{
ch[index] = '\0';
printf("Here is your string: %s\n", ch); //The format seemed weird to me, that's why I changed it, use what you need
}
index = 0;
i++;
}
else
index++;
c = fgetc(fr);
}
fclose(fr);
//return 0; //not needed in C99 or later
}

Related

How to read a file with numbers on each line in C?

I'm trying to read a file that contains 10 numbers then adding them to an array so I can sort them later on but I'm having trouble reading them in. Not sure why this isn't working for me, can someone explain what is wrong? There's only a number on each lines.
10.05
11.01
9.03
double nums[10] = {0};
int count;
if ((fptr = fopen("filename", "r")) == NULL){
printf("Error opening file.\n");
}
while ((c = getc(fptr)) != EOF){
if (c != '\n'){
nums[count] = (double)c;
count = count + 1;
}
}
fclose(fptr);
What is wrong:
You are storing only one character.
You are updating count each times on non-newline characters while updating should be on newline characters.
count is used without being initialized.
Casting to double is not for this usage.
Possible fix:
int c;
FILE* fptr;
char line[1024]; // add line buffer and size tracking
int lineCount = 0;
double nums[10] = {0};
int count = 0; // initialize count
if ((fptr = fopen("filename", "r")) == NULL){
printf("Error opening file.\n");
} else { // avoid using NULL to read file
while ((c = getc(fptr)) != EOF){
if (c == '\n'){ // update nums on newline character
line[lineCount] = '\0'; // don't forget to terminate the string
nums[count] = atof(line); // atof() from stdlib.h is useful to convert string to number
count = count + 1;
lineCount = 0; // start to read next line
} else { // read line contents
line[lineCount] = (char)c;
lineCount = lineCount + 1;
}
}
fclose(fptr);
}
Here I go
#include <stdio.h>
#include <stdlib.h>
int main()
{
double values[10];
int count;
FILE *f = fopen("filename", "r");
if (f == NULL)| {
fprintf(stderr, "Some error message");
return EXIT_FAILURE; // We cannot go any further - file is dead
}
// This is basic - you could overcome error problems
// When able to read (including white space) we carry on until the array is full
// This is an area for improvement - error checking etc.
for (count = 0; count < 10 && fscanf(f, " %lf", &values[count]) != 1; count ++);
fclose(f);
return EXIT_SUCCESS;
}

Why my string getting some extra value? (C program)

I am trying to solve a C Program problem:
Create a program in C that reads a string from a text file and then reorders the string in an odd-even format (first take odd numbered letters and then even numbered letters; example: if the program reads elephant, then the reordered string will be eehnlpat). Then write the string in a different text file. Provide an error-checking mechanism for both reading and writing.
My code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *inputFile;
inputFile = fopen("inpFile.txt", "r");
if (inputFile != NULL) {
FILE *outFile = fopen("outFile.txt", "w");
if (outFile != NULL) {
printf("file created successfully\n");
int i, j = 0;
char strf1[50];
fscanf(inputFile, "%s", &strf1);
char strf2[strlen(strf1)];
for (i = 0; strf1[i] > 0; i++) {
if (i % 2 == 0) {
strf2[j] = strf1[i];
j++;
}
}
for (i = 1; strf1[i] > 0; i++) {
if (i % 2 == 1) {
strf2[j] = strf1[i];
j++;
}
}
fprintf(outFile, "%s\n", strf2);
fclose(outFile);
} else {
printf("file could not be created\n");
}
fclose(inputFile);
} else {
printf("File does not exist.");
}
return 0;
}
I feel all is OK but the problem is if the program reads elephant, then the reordered string given by my program is eehnlpatZ0#. Where extra Z0# is my problem. I don't want that extra thing. But I can't fix it. If anybody can help me to fix it, that will be great.
Your target string is too short: char strf2[strlen(strf1)];. You should at least allow for a null terminator and set it, or simply make the output array the same size as the input array:
char strf2[50];
There are other problems in your code:
In case of error by fopen, it would be advisable to return a non-zero status to the system.
You should pass the array to fscanf(), not a pointer to the array, which has a different type.
You should tell fscanf() the maximum number of characters to read into the array with %49s
You should test the return value of fscanf() and produce an empty output file for an empty input file. The current code has undefined behavior in this case.
The test strf1[i] > 0 is incorrect: characters from the input file might be negative. You should either compute the string length or test with strf1[i] != '\0'
Starting the second loop at i = 1 seems a good idea, but it relies on the silent assumption that strf1 is not an empty string. In your example, if fscanf() succeeds, strf1 is not empty, and if it fails the behavior is undefined because strf1 is uninitialized. Yet it is safer to avoid such optimisations which will bite you if you later move the code to a generic function for which the assumption might not hold.
You must null terminate the output string before passing it to fprintf or specify the length with a %.*s format.
Here is a corrected version:
#include <stdio.h>
int main() {
FILE *inputFile, *outFile;
char strf1[50], strf2[50];
int i, j;
inputFile = fopen("inpFile.txt", "r");
if (inputFile == NULL) {
printf("Cannot open input file inpFile.txt\n");
return 1;
}
outFile = fopen("outFile.txt", "w");
if (outFile == NULL) {
printf("Could not create output file outFile.txt\n");
fclose(inputFile);
return 1;
}
printf("file created successfully\n");
if (fscanf(inputFile, "%49s", strf1) == 1) {
j = 0;
for (i = 0; strf1[i] != '\0'; i++) {
if (i % 2 == 0)
strf2[j++] = strf1[i];
}
for (i = 0; strf1[i] != '\0'; i++) {
if (i % 2 == 1)
strf2[j++] = strf1[i];
}
strf2[j] = '\0';
fprintf(outFile, "%s\n", strf2);
}
fclose(inputFile);
fclose(outFile);
return 0;
}
Here is an alternative with simpler copy loops:
int len = strlen(strf1);
j = 0;
for (i = 0; i < len; i += 2) {
strf2[j++] = strf1[i];
}
for (i = 1; i < len; i += 2) {
strf2[j++] = strf1[i];
}
strf2[j] = '\0';
You have to provide a space for the null-terminator, since you did not provide a space for it, printf cannot know when your string is terminated, so it contiues to print out data from the memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE* inputFile;
inputFile=fopen("inpFile.txt", "r");
if (inputFile!=NULL) {
FILE* outFile=fopen("outFile.txt", "w");
if (outFile!=NULL) {
printf("file created successfully\n");
int i, j=0;
char strf1[50];
fscanf(inputFile, "%s",&strf1);
int inputLength = strlen(strf1) + 1;
char strf2[inputLength];
char strf2[inputLength-1] = '\0';
for(i=0; strf1[i]>0; i++) {
if(i%2==0) {
strf2[j]=strf1[i];
j++;
}
}
for(i=1; strf1[i]>0; i++) {
if(i%2==1) {
strf2[j]=strf1[i];
j++;
}
}
fprintf(outFile, "%s\n",strf2);
fclose(outFile);
}else{
printf("file could not be created\n");
}
fclose(inputFile);
}
else {
printf("File does not exist.");
}
return 0;
}
In C, strings require a Null character, '\0', as the last byte in order to terminate.
Changing the following line of code from
char strf2[strlen(strf1)];
to
char strf2[strlen(strf1) + 1];
will solve this problem.

Replacing a line in a text file with a string

I am learning file handling in C. I wrote code to replace a line in a file with a string input by the user. The replacing progress itself works great, but somehow the first line is always empty and I am able to understand what goes wrong.
Additionally I have some additional questions about file handling itself and about tracking down the mistakes in my code. I understand by now that I should have used perror() and errno. This will be the next thing I will read on.
Why shouldn't I use "w+" establishing the file stream? (A user on here told me to better not use it, unfortunately I couldn't get an explanation)
I tried to use gdb to find the mistake, but when I display my fileStored array I get only numbers, since its obviously an int array, how could I improve the displaying of the variable
What would be a good approach in gdb to track the mistake down I made in the code?
The code:
#include <stdio.h>
#include <stdlib.h>
#define MAXLENGTH 100
int main(int argc, char *argv[]){
FILE *fileRead;
char fileName[MAXLENGTH],newLine[MAXLENGTH];
int fileStored[MAXLENGTH][MAXLENGTH];
short lineNumber, lines = 0;
int readChar;
printf("Input the filename to be opened:");
int i = 0;
while((fileName[i] = getchar()) != '\n' && fileName[i] != EOF && i < MAXLENGTH){
i++;
}
fileName[i] = '\0';
if((fileRead = fopen(fileName, "r")) == NULL){
printf("Error: File not found!\n");
return EXIT_FAILURE;
}
i = 0;
while((readChar = fgetc(fileRead)) != EOF){
if(readChar == '\n'){
fileStored[lines][i] = readChar;
i = 0;
lines++;
}
fileStored[lines][i] = readChar;
i++;
}
fclose(fileRead);
fileRead = fopen(fileName, "w");
printf("Input the content of the new line:");
i = 0;
while((newLine[i] = getchar()) != '\n' && newLine[i] != EOF && i < MAXLENGTH){
i++;
}
newLine[i] = '\0';
printf("There are %d lines.\nInput the line number you want to replace:",lines);
scanf("%d",&lineNumber);
if((lineNumber > lines) || (lineNumber <=0)){
printf("Error: Line does not exist!");
return EXIT_FAILURE;
}
int j = 0;
for(i = 0; i < lines; i++){
if(i == lineNumber-1){
fprintf(fileRead,"\n%s",newLine);
continue;
}
do{
fputc(fileStored[i][j],fileRead);
j++;
}while(fileStored[i][j] != '\n');
j = 0;
}
fclose(fileRead);
return EXIT_SUCCESS;
}

How to count blank lines from file in C?

So what I'm trying to do is to count blank lines, which means not only just containing '\n'but space and tab symbols as well. Any help is appreciated! :)
char line[300];
int emptyline = 0;
FILE *fp;
fp = fopen("test.txt", "r");
if(fp == NULL)
{
perror("Error while opening the file. \n");
system("pause");
}
else
{
while (fgets(line, sizeof line, fp))
{
int i = 0;
if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ')
{
i++;
}
emptyline++;
}
printf("\n The number of empty lines is: %d\n", emptyline);
}
fclose(fp);
You should try and get your code right when posting on SO. You are incrementing both i and emptyline but the use el in your call to printf(). And then I don't know what that is supposed to be in your code where it has }ine. Please, at least make an effort.
For starters, you are incrementing emptyline for every line because it is outside of your if statement.
Second, you need to test the entire line to see if it contains any character that is not a whitespace character. Only if that is true should you increment emptyline.
int IsEmptyLine(char *line)
{
while (*line)
{
if (!isspace(*line++))
return 0;
}
return 1;
}
Before getting into the line loop increment the emptyLine counter and if an non whitespace character is encountred decrement the emptyLine counter then break the loop.
#include <stdio.h>
#include <string.h>
int getEmptyLines(const char *fileName)
{
char line[300];
int emptyLine = 0;
FILE *fp = fopen("text.txt", "r");
if (fp == NULL) {
printf("Error: Could not open specified file!\n");
return -1;
}
else {
while(fgets(line, 300, fp)) {
int i = 0;
int len = strlen(line);
emptyLine++;
for (i = 0; i < len; i++) {
if (line[i] != '\n' && line[i] != '\t' && line[i] != ' ') {
emptyLine--;
break;
}
}
}
return emptyLine;
}
}
int main(void)
{
const char fileName[] = "text.txt";
int emptyLines = getEmptyLines(fileName);
if (emptyLines >= 0) {
printf("The number of empty lines is %d", emptyLines);
}
return 0;
}
You are incrementing emptyline on every iteration, so you should wrap it in an else block.
Let's think of this problem logically, and let's use functions to make it clear what is going on.
First, we want to detect lines that only consist of whitespace. So let's create a function to do that.
bool StringIsOnlyWhitespace(const char * line) {
int i;
for (i=0; line[i] != '\0'; ++i)
if (!isspace(line[i]))
return false;
return true;
}
Now that we have a test function, let's build a loop around it.
while (fgets(line, sizeof line, fp)) {
if (StringIsOnlyWhitespace(line))
emptyline++;
}
printf("\n The number of empty lines is: %d\n", emptyline);
Note that fgets() will not return a full line (just part of it) on lines that have at least sizeof(line) characters.

Program for checking file content. Is there a better way?

I've created a very basic 'debugging' program that checks if a c source file has the same number of opening and closing curly brackets, square brackets and parentheses. I have a code that's fairly simple and it works but the code seems unnecessarily long. I was considering using arrays instead. An array to store each {,[,( and another to store },],) then counting the instance of each and comparing the amounts. But I think that code would be almost as long. What do you guys think?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char fname[20];
char c;
int curlybracket = 0;
int curlybracketr = 0;
int squarebracket = 0;
int squarebracketr = 0;
int parentheses = 0;
int parenthesesr = 0;
printf("Please enter the destination of the file: \n");
scanf("%s", fname);
fp = fopen(fname, "r");
if (fp == NULL)
{
printf("Problem opening file!\n");
exit(0);
}
else
{
printf("File opened correctly\n");
}
while (c != EOF)
{
c = getc(fp);
if (c == '{')
{
curlybracket++;
}
if (c == '[')
{
squarebracket++;
}
if (c == '(')
{
parentheses++;
}
if (c == '}')
{
curlybracketr++;
}
if (c == ']')
{
squarebracketr++;
}
if (c == ')')
{
parenthesesr++;
}
}
if (curlybracket == curlybracketr)
{
printf("There are an equal number of curlybrackets\n");
}
else
{
printf("There is an unequal number of curlybrackets\n");
return 0;
}
if (squarebracket == squarebracketr)
{
printf("There are an equal number of squarebrackets\n");
}
else
{
printf("There are an unequal number of squarebrackets\n");
}
if (parentheses == parenthesesr)
{
printf("There are an equal number of parentheses\n");
}
else
{
printf("There are an unequal number of parentheses\n");
}
return 0;
}
Your program will report no error if the source file is like "([)]", which is actually illegal.
A better solution is to use a stack, which is a last-in-first-out data structure. This section from the wikipedia page illustrates the usage.
When you read an opening symbol from the file, push it onto the stack. If it's a closing symbol, pop the stack. If the symbol popped is not the corresponding opening symbol, report unbalanced error.
At the end of file, if the stack is empty, the symbols in the file are balanced.
This is the most common way that I know to test whether the symbols are balanced.
Use the switch statement for the list of comparisons with c. If you want your code to be even more concise, use a single array of 256 int values to store the occurrence of each character and compare the array values at { and }.
True, program can be re-written in more shorter way by using arrays. It could look something like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char fname[20];
char c;
char brackets[6] = "{}[]()";
int bracketCounts[6] = {0};
char * found;
int i;
printf("Please enter the destination of the file: \n");
scanf("%s", fname);
if ((fp = fopen(fname, "r")) == NULL){
printf("Problem opening file!\n");
return 0x00;
}
printf("File opened correctly\n");
// counting various parentheses
while ((c = getc(fp)) != EOF){
found = strchr(brackets, c);
if (found != NULL) {
bracketCounts[found - brackets]++;
}
}
// dont't forget to close file after reading is done
fclose(fp);
// checking parentheses counters
for (i=0; i < 6; i+=2) {
if (bracketCounts[i] != bracketCounts[i+1]) {
printf("Unbalanced parentheses !\n");
return 0x00;
}
}
printf("All parentheses are OK!\n");
return 0x00;
}
But it is error-prone as #lbs mentioned, it's far more better to use #lbs approach !
Count character occurrences in a string
#include <algorithm>
std::string s = "a(b(c))";
int curlybracket = std::count(s.begin(), s.end(), '(') - std::count(s.begin(), s.end(), ')');
if(curlybracket == 0) /* coool */ else /* fail */
Yust another way to solve the problem

Resources