Free array syntax and defining malloc - c

I am trying to free an array only if it contains something but I am heading a problem probably with syntax, because my code stores data in that array and when I change the file which the array reads from, it has to free that array because if I would like to store those characters in there again, it would just add them, not overwrite them.
The problem is this error in compiler: 0 [main] DNAA 2160 cygwin_exception::open_stackdumpfile: Dumping stack trace to DNAA.exe.stackdump
it does not work, I have no idea what is wrong.
void nacitanie(int *i, char *pole){
//some code....
int a, x=0;
char z;
//reading from file..
//condition if contains data, free it before running again
if (pole != NULL)
{
free (pole);
pole = NULL;
}
while( (z = getc(fp)) != EOF)
{
pole[*i] = z;
(*i)++;
}
for(a=0; a<*i; a++){
if(pole[a] == 'A' || pole[a] == 'C' || pole[a] == 'G' || pole[a] == 'T' || pole[a] == 'a' || pole[a] == 'c' || pole[a] == 'g' || pole[a] == 't'){
x++;
}else{
x--;
}
}
if(x==a){
printf("Sekvenciu sa podarilo nacitat\n");
fflush(stdout);
}else{
printf("Sekvencia nesplna podmienky\n");
fflush(stdout);
}
fclose(fp);
if(fclose(fp) == EOF)
printf("Subor sa nezatvoril");
}
malloc is in main function, where is reading function called
int main() {
int i=0;
char *pole = malloc(MAX);
//vstup z klavesnice
char c;
while(1)
{
switch(c = getchar())
{
case 'v':
trojica();
break;
case 'n':
nacitanie(&i, pole);
break;
case 'h':
histogram(&i, pole);
break;
MAX is defined as 1000 characters for that array

Related

why does only the 1st file reading function executes over multiple programs of the same kind in C language?

This code contains 3 file handling related functions which read from a file named "mno". But only the 1st called function in the main() is working. If the 1st function of the list is commented then, only the 2nd function will work and the third won't. Same goes for the 3rd one
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
void countVowel(char fin[])
{
FILE *fl;
char ch;
int count = 0;
fl = fopen(fin, "r");
while (ch != EOF)
{
ch = tolower(fgetc(fl));
count += (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') ? 1 : 0;
}
fclose(fl);
printf("Number of Vowels in the file \" %s \"-> \t %d \n", fin, count);
}
void countConsonant(char fin[])
{
FILE *fl;
char ch;
int count = 0;
fl = fopen(fin, "r");
while (ch != EOF)
{
ch = tolower(fgetc(fl));
count += (!(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') && (ch >= 'a' && ch <= 'z')) ? 1 : 0;
}
fclose(fl);
printf("Number of Consonant in the file \" %s \"-> \t %d \n", fin, count);
}
void countAlphabet(char fin[])
{
FILE *fl;
char ch;
int count = 0;
fl = fopen(fin, "r");
while (ch != EOF)
{
ch = tolower(fgetc(fl));
count += (ch >= 'a' && ch <= 'z') ? 1 : 0;
}
fclose(fl);
printf("Number of Alphabets in the file \" %s \"-> \t %d \n", fin, count);
}
int main()
{
countVowel("mno"); // output -> 10
countConsonant("mno"); // output -> 0
countAlphabet("mno"); // output -> 0
return 0;
}
Here are the contents of "mno" file ->
qwertyuiopasdfghjklzxcvbnm, QWERTYUIOPASDFGHJKLZXCVBNM, 1234567890
As others have mentioned, your handling of EOF was incorrect:
ch was uninitialized on the first loop iteration
Doing tolower(fgetc(fl)) would obliterate the EOF value.
Using char ch; instead of int ch; would allow a [legitimate] 0xFF to be seen as an EOF.
But, it seems wasteful to have three separate functions to create the three different counts because the most time is spent in the I/O versus the determination of what type of character we're looking at. This is particularly true when the counts are so interelated.
We can keep track of multiple types of counts easily using a struct.
Here's a refactored version that calculates all three counts in a single pass through the file:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
struct counts {
int vowels;
int consonants;
int alpha;
};
void
countAll(const char *fin,struct counts *count)
{
FILE *fl;
int ch;
int vowel;
count->vowels = 0;
count->consonants = 0;
count->alpha = 0;
fl = fopen(fin, "r");
if (fl == NULL) {
perror(fin);
exit(1);
}
while (1) {
ch = fgetc(fl);
// stop on EOF
if (ch == EOF)
break;
// we only care about alphabetic chars
if (! isalpha(ch))
continue;
// got one more ...
count->alpha += 1;
ch = tolower(ch);
// is current character a vowel?
vowel = (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u');
// since we know it's alphabetic, it _must_ be either a vowel or a
// consonant
if (vowel)
count->vowels += 1;
else
count->consonants += 1;
}
fclose(fl);
printf("In the file: \"%s\"\n",fin);
printf(" Number of Vowels: %d\n",count->vowels);
printf(" Number of Consonants: %d\n",count->consonants);
printf(" Number of Alphabetics: %d\n",count->alpha);
}
int
main(void)
{
struct counts count;
countAll("mno",&count);
return 0;
}
For your given input file, the program output is:
In the file: "mno"
Number of Vowels: 10
Number of Consonants: 42
Number of Alphabetics: 52
You are using ch uninitialized. at while (ch != EOF). Every function call after the first has ch equal to 0 at the start, because you forgot to initialize it and the memory was set to -1 before. You can fix it by replacing the loops like this:
int ch;
...
while ((ch = fgetc(fl)) != EOF)
{
ch = tolower(ch);
count += ...;
}
Here ch is getting initialized before you check it and later converted to lowercase.
EDIT:
Note that this only works if ch is an int, so it can handle the value of -1 (EOF) and the byte 255 is not truncated to -1.
EDIT:
At first I said ch was 0 all the time. It was -1. I am so sorry, I swapped it with the null terminator, which is usually the reason for such behavior.

Switch Case to count amount of words and characters

the output window commandI am trying to use switch case in C to figure out the amount of characters, words, newlines in a user input. The code seems legit, no errors raised, however, the output does not work as expected. Please take a look and tell me what I did wrong. Thanks in advance! Here is the code:
#include <stdio.h>
int main()
{
char a, words = 1, characters = 0, newlines = 0;
printf("What do you have in mind? ");
a = getchar();
while ((a=getchar()) && a != EOF)
{
switch (a)
{
case '1':
if (a >= 'a' && a <= 'z' || a >= 'A' && a <= 'Z')
characters++;
printf("The amount of character is %c ", characters);
case '2':
if (a == ' ' || a == '\t')
words++;
printf("The amount of word is %c ", words);
case '3':
if (a == '\t')
newlines++;
printf("The amount of newlines is %c ", newlines);
default:
if (a == EOF)
break;
}
}
return 0;
}
you misunderstand what switch /case means. It does not means 'first case','second case' .. of some conditions, it means (in your specific situation), if the user just typed '1' then do this, it the users just typed '2' then do this,... well you are not typing 1 or 2 or 3.
Simply do this
while ((a=getchar()) && a != EOF)
{
if (a >= 'a' && a <= 'z' || a >= 'A' && a <= 'Z')
characters++;
printf("The amount of character is %c ", characters);
if (a == ' ' || a == '\t')
words++;
printf("The amount of word is %c ", words);
if (a == '\t')
newlines++;
printf("The amount of newlines is %c ", newlines);
}
Also you must change a to be an int
#include<stdio.h>
int
main ()
{
int ch_count = 0, line_count = 0, word_count = 0, choice;
char ch;
FILE *fp;
fp = fopen ("wordcount.txt", "r"); //make a seperate file "wordcount.txt" and Read the Test content from it.
if (fp == NULL) // Show error if previous step is not done i.e wordcount.txt file is not made.
{
perror ("FILE NOT FOUND.");
return (-1);
}
else // If file is opened properly then ask for NO. of counts.
{
printf ("Select the Following Option-------\n"
"1 - Number of Characters\n"
"2 - Number of Words\n"
"3 - Number of Lines\n");
scanf ("%d", &choice);
}
{
switch (choice) // switch to desired case as per choice of user.
{
case 1: // CASE 1 - To count the characters in the file.
{
while ((ch = fgetc (fp)) && ch != EOF)
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
ch_count++;
}
printf ("Number of Characters : %d\n", ch_count);
break;
case 2: // CASE 2: To count total number of words
while ((ch = fgetc (fp)) && ch != EOF)
if ((ch == ' ') || (ch == '\t') || (ch == '\n') || (ch == '\0'))
{
word_count++;
}
printf ("Numbers of Words : %d\n", word_count);
break;
case 3: // CASE 3: To count total number of lines
while ((ch = fgetc (fp)) && ch != EOF)
if ((ch == '\n') || (ch == '\0'))
{
line_count++;
}
printf ("Numbers of lines : %d\n", line_count);
break;
} //switch closed
}
fclose (fp); //file closed
return 0;
}

Low level IO read() and write()

I am working on a program that is in multiple parts that build off each other. The first program has to read from a file and write the content split up by spaces to a new file. Program two is supposed to take this words and add pig latin to them based on the rule of whether it starts with a vowel or a consonant and appending some string at the end depending on which it started with. I am able to open the file and read from the contents, but I am having trouble finding and appending the proper rules to print to the new file.
int processingWord = 1; //0 is not in the middle of a word and 1 is in the middle
char c;
int bytes; //Should be holding the position of the pointer in the file
while((bytes = read(fileRead, &c, sizeof(c))) > 0) {
//printf("%c", c);
if(processingWord == 0) {
processingWord = 1;
}
if(processingWord == 1) {
//Figure out if a vowel or not
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
//Increment the first counter
shard1Count++;
}
//Get to the end of the string
if(c == '\n') {
c = 'r';
write(fileWrite, &c, sizeof(c));
c = 'a';
write(fileWrite, &c, sizeof(c));
c = 'y';
write(fileWrite, &c, sizeof(c));
c = '\n';
write(fileWrite, &c, sizeof(c));
processingWord = 0;
}
}
write(fileWrite, &c, sizeof(c));
}
This is where I am trying to find and append the new "ray" string at the end of the word if it starts with a vowel. The text files look like this
It
is
the
Zucca
Gigantopithecus,
or
Great
Pumpkin,
Charlie
Brown.
And output is supposed to look like this in a new file
Itray
isray
hetay
uccaZay
igantopithecusGay,
orray
reatGay
umpkinPay,
harlieCay
rownBay.
EDIT: processsingWord was an idea I had to check if i was at the end of the line before I checked for vowels and what not. But the logic didn't workout and the output was all jibberish.
My current output file looks like this:
Itray
isray
theray
Zuccaray
Gigantopithecus,ray
orray
Greatray
Pumpkin,ray
Charlieray
Brown.ray
ray
Here is an implementation that should work:
void doStuff(void);
int startsWithVowel(char c);
int isALetter(char c);
void doStuff(){
int processingWord = 0;
int already_latin = 0;
char c = 0;
char first_letter = 0;
while(read(fileRead, &c, sizeof(c)) > 0) {
if(processingWord == 0) {
processingWord = 1;
if(!startsWithVowel(c)){ //append constants to the end of the word in pig latin *EDIT*
first_letter = c;
continue;//Here we do not fall through and write
}
}
else{
if(isALetter(c)){ //This is the general case of just writing the read character
write(fileWrite, &c, sizeof(c));
}
else if(c != '\n'){ //Here is handling for , and . special characters
if(isALetter(first_letter)){ //we hit a . or , with a vower word, need to add first letter then "ray"
write(fileWrite, &first_letter, sizeof(first_letter));
}
write(fileWrite, "ray", sizeof("ray"));
write(fileWrite, &c, sizeof(c));
already_latin = 1;
}
else if(c == '\n') { //here is the end of the string
if(isALetter(first_letter)){
write(fileWrite, &first_letter, sizeof(first_letter));
}
if(!already_latin){
write(fileWrite, "ray", sizeof("ray"));
}
write(fileWrite, &c, sizeof(c));
processingWord = 0; //reset all the flags for the next word.
first_letter = 0;
already_latin = 0;
}//end of '\n'
}//end of if/else block
}//end of while loop
}//end of function
/* =========================================================
return true (1) if the character is a vowel and 0 otherwise
============================================================ */
int startsWithVowel(char c){
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
return 1;
}
return 0;
}
/* =========================================================
return true (1) if the character is a letter and 0 otherwise
============================================================ */
int isALetter(char c){
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))){
return 1;
}
return 0;
}
There is still a bunch of unused stuff like the bytes variable, and things could certainly be cleaner, but this should work how you need it to. Try to run it and let me know how it goes, if im still here ill update any bugs tonight
EDIT
Looks like i did it backwards, only swapping vowels (instead of constants). my pig Latin is rusty.
Ok I made a local string to test the parsing online with codechef.com/ide, you can copy and paste this in there to verify. Change the printfs to writes, which mimic the printfs and i think youre good to go:
#include <stdio.h>
#include <string.h>
void doStuff(void);
int startsWithVowel(char c);
int isALetter(char c);
char * str = "It\nis\nthe\nZucca\nGigantopithecus,\nor\nGreat\nPumpkin,\nCharlie\nBrown.";
int main(void) {
doStuff();
return 0;
}
void doStuff(){
int processingWord = 0;
char c = 0;
char first_letter = 0;
int already_latin = 0;
//while(read(fileRead, &c, sizeof(c)) > 0) {
while(strlen(str) > 0){ //Made local for testing, no file io here
c = str[0];
str++; //end of local nonsense you wont have to use
if(processingWord == 0) {
processingWord = 1;
if(!startsWithVowel(c)){
first_letter = c;
continue;//Here we don not fall through and write
}
}
if(processingWord == 1) {
if(isALetter(c)){ //This is the general case of just writing the read character
//write(fileWrite, &c, sizeof(c));
printf("%c",c);
//printf(" SHOULD PRINT FIRST LETTER VOWEL HERE ");
}
else if(c != '\n'){ //Here is handling for , and . special characters
if(isALetter(first_letter)){ //we hit a . or , with a vower word, need to add first letter then "ray"
//write(fileWrite, &first_letter, sizeof(first_letter));
printf("%cay%c",first_letter,c);
}
else{
//write(fileWrite, "ray", sizeof("ray"));
//write(fileWrite, &c, sizeof(c));
printf("ray%c", c);
}
already_latin = 1;
}
else if(c == '\n') { //here is the end of the string
if(!already_latin){
if(isALetter(first_letter)){
//write(fileWrite, &first_letter, sizeof(first_letter));
printf("%cay",first_letter);
//printf(" SHOULD PRINT FIRST LETTER CONSTANT HERE ");
}
else{
//write(fileWrite, "ray", sizeof("ray"));
printf("ray");
}
}
//write(fileWrite, &c, sizeof(c));
printf("%c", c);
processingWord = 0;
first_letter = 0;
already_latin = 0;
}//end of '\n'
}//end of if/else block
}//end of while loop
}//end of function
/* =========================================================
return true (1) if the character is a vowel and 0 otherwise
============================================================ */
int startsWithVowel(char c){
if(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') {
return 1;
}
return 0;
}
/* =========================================================
return true (1) if the character is a letter and 0 otherwise
============================================================ */
int isALetter(char c){
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))){
return 1;
}
return 0;
}
OUTPUT:
Itray
isray
hetay
uccaZay
igantopithecusGay,
orray
reatGay
umpkinPay,
harlieCay
rownBay.

c how to check the first char of an array

I am trying to take in 10 characters over a serial console and add them to an array called buffer. The first character needs to be 'L' or 'S' and the next characters either '1' or '0'.
The code passes the first if statement ok. But the line if((buffer[0] != 'L') || (buffer[0] != 'S')) doesn't seem to work even when I enter 'L' OR 'S'.
Is there anything wrong with using the buffer[0] != notation?
int main(void)
{
char ch;
char buffer[10] = "";
putstring("Enter 9 characters beginning with 'L' or 'S' and 8 digits\r\n");
for (int i = 0; i < 9; i++) {
ch = getcharacter();
if ((ch == '0') || (ch == '1') || (ch == 'L') || (ch == 'S')) {
buffer[i] = ch;
//check first character
if((buffer[0] != 'L') || (buffer[0] != 'S')) {
printf("First letter must be L or S\r\n");
goto error;
}
error:
return -1;
}
}
}
int getcharacter(void) {
char c = 0;
const uint32_t recieve_ready = 1 << 7;
//disable interrupt for a read ready
*uart_control_reg = 0;
while (1) {
//check if RRDY bit is set
if ((*uart_status_reg) & recieve_ready) {
c = *uart_rxdata_reg;
break;
}
}
return ((char) c);
}
if((buffer[0] != 'L') || (buffer[0] != 'S'))
is wrong, you need
if((buffer[0] != 'L') && (buffer[0] != 'S'))
or
if (!(buffer[0] == 'L' || buffer[0] == 'S'))
Your original code was "if the char is not L or the char is not S" which is always true. If the char is L, then the second part was true, making the whole if statement true.
Just noticed Chris Turner's comment above. The return -1 is always executed, move it to replace the line that says goto error.
Try using
if((buffer[0] != 'L') && (buffer[0] != 'S'))
instead of
if((buffer[0] != 'L') || (buffer[0] != 'S'))
Just some logic problem here. According to your code, the char needs to be equal to 'L' AND 'S' to avoid the condition, which is never the case !

How to expect different data types in scanf()?

I'm developing a chess game in C just for practicing. At the beginning of the game, the user can type 4 things:
ROW<whitespace>COL (i.e. 2 2)
'h' for help
'q' to quit
How can I use a scanf to expect 2 integers or 1 char?
Seems like it would be most sensible to read a whole line, and then decide what it contains. This will not include using scanf, since it would consume the contents stdin stream.
Try something like this :
char input[128] = {0};
unsigned int row, col;
if(fgets(input, sizeof(input), stdin))
{
if(input[0] == 'h' && input[1] == '\n' && input[2] == '\0')
{
// help
}
else if(input[0] == 'q' && input[1] == '\n' && input[2] == '\0')
{
// quit
}
else if((sscanf(input, "%u %u\n", &row, &col) == 2))
{
// row and column
}
else
{
// error
}
}
It's better to avoid using scanf at all. It usually causes more trouble than what it solves.
One possible solution is to use fgets to get the whole line and then use strcmp to see if the user typed 'h' or 'q'. If not, use sscanf to get row and column.
This one is just using scanf
#include <stdio.h>
int main()
{
char c;
int row, col;
scanf("%c", &c);
if (c == 'h')
return 0;
if (c == 'q')
return 0;
if (isdigit(c)) {
row = c - '0';
scanf("%d", &col);
printf("row %d col %d", row, col);
}
return 0;
}
int row, col;
char cmd;
char *s = NULL;
int slen = 0;
if (getline(&s, &slen, stdin) != -1) {
if (sscanf(s, "%d %d", &row, &col) == 2) {
free(s);
// use row and col
}
else if (sscanf(s, "%c", &cmd) == 1) {
free(s);
// use cmd
}
else {
// error
}
}
P.S.: those who did not read and understand my answer carefully, please respect yourself, DO NOT VOTE-DOWN AT WILL!
Beside "get the whole line and then use sscanf", read char by char until '\n' was entered is also a better way. If the program encountered 'h' or 'q', it could do the relevant action immediately, meanwhile you cloud also provide a realtime analysis for the input stream.
example:
#define ROW_IDX 0
#define COL_IDX 1
int c;
int buffer[2] = {0,0};
int buff_pos;
while( (c = getchar())) {
if (c == '\n') {
//a line was finished
/*
row = buffer[ROW_IDX];
col = buffer[COL_IDX];
*/
buff_pos = 0;
memset(buffer , 0 , sizeof(buffer));//clear the buffer after do sth...
} else if (c == 'h') {
//help
} else if (c == 'q') {
//quit
} else {
//assume the input is valid number, u'd better verify whether input is between '0' and '9'
if (c == ' ') {
//meet whitespace, switch the buffer from 'row' to 'col'
++buff_pos;
} else {
buffer[buff_pos%2] *= 10;
buffer[buff_pos%2] += c - '0';
}
}
}

Resources