#include <stdio.h>
int vowel_count(char n[]){
int hasil = 0;
char vowel[] = "aiueoyAIUEOY";
for (int i = 0; i < 50; i++)
{
for (int x = 0; x < 12; x++)
{
if (n[i] == vowel[x])
{
hasil++;
}
}
}
return hasil;
}
int main(void){
int amount;
char values[50], unknown[10];
char vowel[] = "AIUEOYaiueoy";
FILE* fp = fopen("zValues.txt", "r");
fscanf(fp, "%d", &amount);
fgets(unknown, 10, fp);
for (int n = 0; n < amount; n++)
{
fgets(values, 50, fp);
printf("%d ", vowel_count(values));
}
fclose(fp);
}
here is the zValues.txt:
5
abracadabra
pear tree
o a kak ushakov lil vo kashu kakao
my pyx
riszky hermawan
when i run the code,it shows:
5 4 13 12 12
see the problem? it's wrong answer"
ouput must be like this
5 4 13 2 5
Since your code uses the function, fgets to read the file content, the function vowel_count should not iterate over 50 array characters. Some of the lines (read from the file) may be of different length. Consequently, iterating beyond 50 characters may fetch random values from memory, which may include vowels.
Therefore you just need to adapt the function vowel_count, namely change:
for (int i = 0; i < 50; i++)
to
for (int i = 0; n[i] != '\0'; i++)
Moreover, IMO it is better to do :
for (int x = 0; vowel[x] != '\0'; x++)
instead of
for (int x = 0; x < 12; x++)
You do not need to hardcode the size of the array because when you write char vowel[] = "aiueoyAIUEOY", the terminal character (i.e. '\0') gets added automatically at the end of it. Although in your case is not very problematic, because the number of vowels will probably remain the same, in other cases, it is prone to bugs.
Related
So, I'm doing an exercise, and I want to sort a list of float numbers. When I used for loop, it worked perfectly. When I changed to while loop, it shows nothing. I already tried to declare a different variable for each while loop, but remains the same. I'm getting this warning for the file ex005.c:
Please, input one non-integer values: 45.3
Please, input one non-integer values: 32.2
Please, input one non-integer values: 34.5
zsh: segmentation fault ./"ex005"
Here is my code:
#include <stdio.h>
int main(void)
{
float three_numbers[3];
char support_var;
int size_array;
int i;
int z;
size_array = 3;
z = size_array - 1;
i = 0;
while (i < size_array)
{
printf("Please, input one non-integer values: ");
scanf("%f", &three_numbers[i]);
i++;
}
i = 0;
while (i < size_array)
{
while (z != i)
{
if (three_numbers[i] < three_numbers[z])
{
support_var = three_numbers[i];
three_numbers[i] = three_numbers[z];
three_numbers[z] = support_var;
}
z--;
}
i++;
}
i = 0;
while (i < size_array)
{
printf("The %dth place is %.1f. \n", i + 1, three_numbers[i]);
i++;
}
return (0);
}
You probably want to set z in the inner loop otherwise it causes out of bound access of three_numbers[z]. Also, your support_var should be a float. Use the typeof operator if available (with gcc 10.2.1-6 it's still an extension so -std=gnu18):
#include <stdio.h>
#define ARRAY_SIZE 3
int main(void) {
float three_numbers[ARRAY_SIZE];
for(int i = 0; i < ARRAY_SIZE; i++) {
printf("Please, input one non-integer values: ");
scanf("%f", three_numbers + i);
}
for(int i = 0; i < ARRAY_SIZE; i++) {
for(int z = ARRAY_SIZE - 1; z != i; z--) {
if(three_numbers[i] < three_numbers[z]) {
// typeof (*three_numbers) support_var = three_numbers[i];
float support_var = three_numbers[i];
three_numbers[i] = three_numbers[z];
three_numbers[z] = support_var;
}
}
}
for(int i = 0; i < ARRAY_SIZE; i++) {
printf("The %dth place is %.1f. \n", i + 1, three_numbers[i]);
}
}
Not sure why you don't like for-loops but it makes your code easier to read. Also replaced int array_size with a constant ARRAY_SIZE. Minimizing scope of variables makes is usually a good idea.
I have array and I am trying to print this array as sub blocks, where each block has size = 5.
the out put of this code not as I expected it just print the first 5 values. How to print the array as sub blocks?
int arr[298] = {some int values};
int in = 0;
int siz = 298;
int ii;
int rang = 5;
for (int i = 0; i < siz; i++) {
if (in <= siz) {
for (ii = in; ii < 5; ii++) {
printf("arr=%d \n", arr[ii]);
}
printf("------------\n");
}
ind = ind + rang;
}
Following your request for clarification in the comment section, there are a few problems with your code, for me the biggest one is that it's needlessly complicated, but the one you are looking for is in this line:
ind = ind + rang;
ind is is not declared in your code but I assume you mean in, the first time the inner loop runs in(ind) is 0 so it all goes well, after that in will be 5, you assign it to ii and the condition ii < 5 will never be true again, the body of the loop will never be executed.
I suppose you could fix it by using in as index for the array and scrap rang since it isn't needed, something like this:
int arr[298] = {some int values};
int in = 0;
int siz = 298;
for (int i = 0; i < siz; i++) {
//if (in < siz) { moving this into the for loop
for (int ii = 0; ii < 5 && in < siz; ii++, in++) {
printf("arr=%d \n", arr[in]);
}
printf("------------\n");
//}
}
Live demo: https://godbolt.org/z/YzG9sno1n
But you don't need a nested loop, there are a few ways you can do this, a simple one is to have a variable that controls the block size:
int arr[298] = {some int values};
int siz = 298;
int count = 5;
for (int i = 0; i < siz; i++) {
printf("arr=%d \n", arr[i]);
count--;
if (count == 0) {
printf("------------\n");
count = 5;
}
}
Live demo: https://godbolt.org/z/b4e8vWfhM
In the above code count serves as the control variable, the value in the index is printed 5 times and when it reaches 0 a separator is printed and it resets and starts the new block.
Another possible option is to use the index itself to separate the blocks, you know the remainder of a division is 0 when the numerator is divisible by the denominator, you can use that to your advantage:
int arr[298] = {some int values};
int siz = 298;
for (int i = 0; i < siz; i++) {
if (i % 5 == 0) { // && i != 0 if you want to skip the initial separator
printf("------------\n");
}
printf("arr=%d \n", arr[i]);
}
Live demo : https://godbolt.org/z/nne3z38rY
Finally you can/should use a constant value for size:
#include <stdio.h>
#define SIZE 298
int main() {
int arr[SIZE] = {some int values};
for (int i = 0; i < SIZE; i++) {
if (i % 5 == 0 && i != 0) { // skipping the initial separator
printf("------------\n");
}
printf("arr=%d \n", arr[i]);
}
}
Live demo: https://godbolt.org/z/Mc4Yh4cav
Instead of several for loops, you can use a single while loop.
int arr[298 ]={Some int Values};
int ind =0;
int siz= 298 ;
printf("------------\n");
while(ind<=siz-1){
printf("arr=%d \n",arr[ind]);
ind++;
if(ind%5==0){
printf("------------\n");
}
}
In this, you print the elements through 0 to 297, with a line of dashes printed if the index is divisible by 5, that is after every fifth element.
In the following code, I am trying to read char by char from a file and store each char in a two dimensional array. After that I want to print each char in the array with its coordinates (i and j):
#include <stdio.h>
#pragma warning(disable:4996)
int main(){
char grid[3][5];
FILE *file;
file = fopen("input.txt", "r");
int c;
if (file == NULL){
perror("Error in reading the file");
}
else{
int j=0;
for (int i = 0; i < 3; i++)
{
while (j<5)
{
grid[i][j] = fgetc(file);
j++;
}
j = 0;
}
}
int length = sizeof grid / sizeof grid[0][0];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%c %d %d \n", grid[i][j], i, j);
}
}
printf("\n");
return 0;
}
The file that I read from looks like:
ABCDE
FGHIJ
KLMNO
I want the result to be like:
A 0 0
B 0 1
...
But the real results that I got is:
A 0 0
B 0 1
C 0 2
D 0 3
E 0 4
1 0
F 1 1
G 1 2
H 1 3
I 1 4
J 2 0
2 1
K 2 2
L 2 3
M 2 4
As you can see, the second row is printed with a space first and the same with the third row. Also, the last two letters N and O are not printed. Can someone help me solving this issue?
Change this bit of code
for (int i = 0; i < 3; i++)
{
while (j<5)
{
grid[i][j] = fgetc(file);
j++;
}
j = 0;
}
To add in an if statement which will check to make sure the character it read in is not a newline character \n. The finished code will look like this:
for (int i = 0; i < 3; i++)
{
while (j<5)
{
char c = fegetc(file);
if(c != '\n')
{
grid[i][j] = fgetc(file);
j++;
}
}
j = 0;
}
Fiddling Bits suggested that the inner loop be changed to a for loop (for readability). I would agree, however it does have the drawback of having to put j-- in the else part of the if statement, versus not even needing an else statement. You can view the above fix and this fix with the inner loop changed to a for loop, and decide which one you think has the best readability in this case. This code represents that change as well as the fix for the initial problem:
for (int i = 0; i < 3; i++)
{
for(int j = 0; j < 5; j++)
{
char c = fegetc(file);
if(c != '\n')
{
grid[i][j] = fgetc(file);
} else {
j--;
}
}
}
Try to add another fgetc(file); after the j=0;
(Without any assignment).
It will pull the new line char from your file
int main(void)
{
int i,j=0,k; //initialization
char equation[100]; //input is a string (I think?)
int data[3]; //want only 3 numbers to be harvested
printf("Enter an equation: ");
fgets(equation, 100, stdin); //not so sure about fgets()
for (i = 0; i < equation[100]+1; i++) { //main loop which combs through
//"equation" array and attempts
//to find int values and store
while (j <= 2) { //them in "data" array
if (isdigit(equation[i])) {
data[j] = equation[i]
j++;
}
}
if (j == 2) break;
}
for (k = 0; k <= 2; k++) { //this is just to print the results
printf("%d\n", data[k]);
}
return 0;
}
Hello! This is my program for my introductory class in C, I am trying to comb through an array and pluck out the numbers and assign them to another array, which I can then access and manipulate.
However, whenever I run this I get 0 0 0 as my three elements in my "data" array.
I am not sure whether I made an error with my logic or with the array syntax, as I am new to arrays.
Thanks in advance!!! :)
There are a few problems in your code:
for (i = 0; i < equation[100]+1; i++) { should be something like
size_t equ_len = strlen(equation);
for (i = 0; i < equ_len; i++) {
Whatever the input is, the value of equation[100] is uncertain, because char equation[100];, equation only has 100 element, and the last of them is equation[99].
equation[i] = data[j]; should be
data[j] = equation[i];
I suppose you want to store digit in equation to data.
break; should be deleted.
this break; statement will jump out of the while loop, the result is you will store the last digit in equation to data[0] (suppose you have switched data and equation, as pointed out in #2).
If you want the first three digits in equation, you should do something like
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
printf("%d\n", data[k]); should be printf("%c\n", data[k]);
%d will give the ASCII code of data[k], for example, if the value of data[k] is character '1', %d will print 50 (the ASCII code of '1') instead of 1.
Here is my final code, based on the OP code:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
int i,j,k;
char equation[100];
int data[3];
int equ_len;
printf("Enter an equation: ");
fgets(equation, 100, stdin);
equ_len = strlen(equation);
j = 0;
for (i = 0; i < equ_len; i++) {
if (j <= 2 && isdigit(equation[i])) {
data[j] = equation[i];
j++;
}
if (j > 2) break;
}
for (k = 0; k <= 2; k++) {
printf("%c\n", data[k]);
}
return 0;
}
Tested with:
$ ./a.out
Enter an equation: 1 + 2 + 3
1
2
3
Need to figure out a code that counts all the repeating symbols in a string. As you can see below, so far so good.
And here starts the tricky part, at the end of the code I want to output symbols in an order they were typed which had for example 2 occurences in a string, and I got problems figuring that out.
int counts[256] = { 0 };
int i;
size = strlen(text);
for (i = 0; i < size; i++) {
counts[(int)(text[i])]++;
}
for (i = 0; i < 256; i++) {
printf("The %d. character has %d occurrences.\n", i, counts[i]);
}
Just iterate through the source string again and for each character look into your counts array.
If you don't want to print the same statistics for every occurence of repeating character, you can reset the corresponding counts value to zero just after you print the statistics, and have an additional check before printing.
for(i = 0; i < size; i++) {
if(counts[(int)(text[i])] == 2)
printf("%d", (int)(text[i]));
The first line loops through your source string for the order of occurences.
The second line checks if it was captured in the counts array as occuring only twice.
If it was we print the char code on the third line.
To only print the character once:
for(i = 0; i < size; i++) {
if(counts[(int)(text[i])] == 2) {
printf("%d", (int)(text[i]));
counts[(int)(text[i])] = 0;
}
}
Here is an implementation of Inspired's answer:
int counts[256] = { 0 };
char text[] = "Hello, world!";
int i, size = strlen(text);
for (i = 0; i < size; i++)
{
counts[(unsigned int)(text[i])]++;
}
for (i = 0; i < size; i++)
{
if (counts[(unsigned int)text[i]] > 1)
{
printf("%c", text[i]);
counts[(unsigned int)text[i]] = 0; // Remove to print repeats.
}
}
Make a key,count pair, like:
#include <string.h>
#include <stdio.h>
int main()
{
char* text = "count this text";
char *keys = new char[strlen(text)];
int* count = new int[strlen(text)];
int last = 0; int j=0;
for(int i=0; i<strlen(text); i++){
for(j=0; j<last; j++){
if(keys[j]==text[i]) break;
}
if(keys[j]==text[i]){
count[j]++;
} else {
keys[last]=text[i];
count[last]=1;
last++;
}
}
for(int i=0; i<last; i++){
printf("%c %d\n", keys[i], count[i]);
}
}
so you keep the order in the text and get the count.
On execution the output is:
c 1
o 1
u 1
n 1
t 4
2
h 1
i 1
s 1
e 1
x 1