Passing an updated Char array back through pointers - c

I'm trying to pass back an updated char array to the original main() function, however when i try to copy over the array with a pointer before it it gives me "Char " differs in levels of indirection from char() [15]'
This is a ISBN validator program.
Here it is:
int main(void)
{
int divisible;
char choice, trash;
char code[15];
do
{
printf("Enter an ISBN (book) number:\n");
fgets(code, 15, stdin);
printf("The ISBN entered is:%s\n", code);
divisible = testISBN(&code);
if (divisible == 1)
printf("\n\n\tValid ISBN Number\n");
else
printf("\n\n\tInvalid ISBN Number\n");
printf("\nDo you wish to continue? (Y/N)\n");
choice = getchar();
trash = getchar();
} while (toupper(choice) != 'N');
return 0;
}
int testISBN(char *code)
{
int i;
int sum = 0;
int weight = 10;
char codefinal[10];
int x = 0;
for (i = 0; i<15; i++)
{
int chVal;
if ((i == 9) && (toupper(code[i]) == 'X'))
{
printf("%c",code[i]);
chVal = 10;
}
else
{
chVal = code[i] - '0';
}
if (chVal == 0 || chVal == 1 || chVal == 2 || chVal == 3 || chVal == 4 || chVal == 5 || chVal == 6 || chVal == 7 || chVal == 8 || chVal == 9) {
char y = (char)chVal;
codefinal[x] = y;
x++;
}
sum += chVal * weight;
weight--;
}
printf("sum is %d", sum);
for (i = 0; i < 15; i++) {
*code[i] = codefinal[i];
printf("%c", code);
}
return (sum % 11) == 0;
}
At the very bottom where i said *code[i] = codefinal[i] is where i get the issue. I'm just trying to pass back by pointer my new updated array of numbers to my main.

Do following changes in your code:
Change prototype of function int testISBN(char* code) to int testISBN(char code[])
Change calling from testISBN(&code); to testISBN(code);
Change line *code[i] = codefinal[i]; to code[i] = codefinal[i];
In line printf("%c", code); you are printing not the value but the address of code[]. So change it to printf("%c", code[i]);. Note that code[] contains some non printable characters also.
Suggestion: You can change line if (chVal == 0 || chVal == 1 || chVal == 2 || chVal == 3 || chVal == 4 || chVal == 5 || chVal == 6 || chVal == 7 || chVal == 8 || chVal == 9) to if((chVal >= 0) && (chVal <= 9)) for simplicity.

Just pass code as is it will decay into pointer.
char code[15];
divisible = testISBN(code);
You may want to change testISBN signature to
int testISBN(char code[15]);
This way you have a higher chances to get compiler warning if you mess up indices.
Simple example:
#include <stdio.h>
void func(char arr[3]) {
arr[0] = 'H';
arr[1] = 'i';
arr[2] = 0;
}
int main() {
char arr[3] = {0};
func(arr);
printf("%s", arr);
}
Prints "Hi"
As commenters mentioned your code has other issues such as memory out of bounds access. To ease your life spend some time with your compiler's manual and learn how to turn on all the warnings, they indicate code issues most of the time.

Related

error in finding no. of vowels in a string

//schecking no of vowels in a string.
#include <stdio.h>
#include <string.h>
void printstring();
int main() {
char sai[8]; //allows 8 charecters.
char a,e,j,o,u; //I have used j as i have already used i for iteration
fgets(sai, 8, stdin); //going to enter my name
char *ptr = sai; ///setting pointer for string
int i,t = 0;
for(i = 0;i <= 7; i++){
if(*(ptr+i) == a) || (*(ptr+i) == e) || (*(ptr+i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u){
t = t+1;
}
else {
t = t;
}
}
printf("%d", t);
}
OUTPUT:
The compiler generated an error:
jill.c: In function 'main':
jill.c:12:23: error: expected expression before '||' token
if(*(ptr+i) == a) || (*(ptr+i) == e) || (*(ptr+i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u){
^~
I expected the number of vowels as output, but an error has occured. Where am I going wrong?
Below listed points are incorrect in your code
Englobe the full condition between brackets in your if condition is missing
Single quotes are missing for character in your if statements. please go through here more explanation.
As comment from  Ted Lyngmo, Craig Estey a,e,j,o,u are uninitialized.
if (*(ptr + i) == a) ||(*(ptr + i) == e) || (*(ptr + i) == j) || (*(ptr + i) == o) || (*(ptr + i) == u)
changed to
if((ptr[i] == 'a') || (ptr[i] == 'e') || (ptr[i] == 'j') || (ptr[i] == 'o') || (ptr[i] == 'u'))
code
//schecking no of vowels in a string.
#include <stdio.h>
#include <string.h>
void printstring();
int main()
{
char sai[8];//allows 8 charecters.
char a,e,j,o,u; //I have used j as i have already used i for iteration
fgets(sai, 8, stdin); //going to enter my name
char *ptr = sai; ///setting pointer for string
int i,t = 0;
for(i = 0;i <= 7; i++)
{
if((ptr[i] == 'a') ||
(ptr[i] == 'e') ||
(ptr[i] == 'j') ||
(ptr[i] == 'o') ||
(ptr[i] == 'u'))
{
t = t+1;
}
else
{
t = t;
}
}
printf("%d", t);
}
Link for below Output:
apple
2

I am getting this Segmentation fault (core dumped) error. Does anyone knows why?

Basically my project is for finding how many vowels and constants a string that I input has. But it doesn't work and I don't know why. I checked if the malloc works but it works find I guess.
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define E_A_LETTERS 26
int check_vowels(char *p_string);
int main(void) {
// Here your code !
char *string;
int vowels;
int constants;
printf("Enter a string: ");
gets(string);
string = (char *)malloc(strlen(string) * sizeof(char));
if (string == NULL) {
printf("Unable to allocate memory...");
exit(0);
}
vowels = check_vowels(&string[0]);
constants = E_A_LETTERS - vowels;
printf("\nNumber of vowels : %d", vowels);
printf("\nNumber of constants : %d\n", constants);
free(string);
}
int check_vowels(char *p_string) {
int i = 0;
int count = 0;
while (1) {
if(*(p_string + i) == 65 || *(p_string + i) == 69 || *(p_string + i) == 73 || *(p_string + i) == 79 || *(p_string + i) == 85)
count++;
if(*(p_string + i) == 97 || *(p_string + i) == 101 || *(p_string + i) == 105 || *(p_string + i) == 111 || *(p_string + i) == 117)
count ++;
if(*(p_string + i) == '\0')
break;
i++;
}
return count;
}
Output Example - Error :
Enter a string: apples
Segmentation fault (core dumped)
There are multiple problems in your code:
gets(string) attempts to reads input into an invalid address as string is an uninitialized pointer. You should pass an array.
gets is an obsolete function that cannot be used safely. You should use fgets() instead.
the number of consonants is not (26 - number_of_vowels). You should count the number of letters and subtract the number of vowels.
it is much more readable and portable to use character constants such as 'A' than actual ASCII codes like 65.
Here is a modified version:
#include <stdio.h>
int count_vowels(const char *p_string);
int count_letters(const char *p_string);
int main(void) {
char string[100];
int vowels;
int constants;
printf("Enter a string: ");
if (fgets(string, sizeof string, stdin) == NULL) {
printf("No input\n");
return 1;
}
vowels = count_vowels(string);
constants = count_letters(string) - vowels;
printf("Number of vowels: %d\n", vowels);
printf("Number of constants: %d\n", constants);
return 0;
}
int count_vowels(const char *p) {
int count = 0;
for (int i = 0; p[i] != '\0'; i++) {
if (p[i] == 'A' || p[i] == 'E' || p[i] == 'I' || p[i] == 'O' || p[i] == 'U')
count++;
if (p[i] == 'a' || p[i] == 'e' || p[i] == 'i' || p[i] == 'o' || p[i] == 'u')
count++;
}
return count;
}
int count_letters(const char *p) {
int count = 0;
for (int i = 0; p[i] != '\0'; i++) {
/* assuming A-Z and a-z are contiguous, as is the case in ASCII */
if ((p[i] >= 'A' && p[i] <= 'Z') || (p[i] >= 'a' && p[i] <= 'z'))
count++;
}
return count;
}

getting 0 for return value when using atoi

Im taking a numerical input in my command line arguments and if there is a '+' or '-' character im trying to strip it away and only leave the numbers. Ive managed to strip the leading character but whenever i try assigning the value of the string with atoi without the leading character i keep getting a value of 0. Wondering what i could be doing wrong because whenever i print out the string its the same exact string except no leading character so shouldnt the atoi function convert that to a number? The ReadLine() function takes in a string and dynamically allocates memory depending on the size of the user input.
char *val = ReadLine();
int i, size = strlen(val);
int count = 0;
int num = 10;
char *newVal = (char*)malloc(sizeof(char) * 10);
for(i = 0; i < size; i++) //checks once to make sure its proper formatting, if count == size then input is correct
{
if((val[0] == '+' && i == 0) || (val[0] == '-' && i == 0))
{
//printf("check\n");
count++;
i++;
}
if(val[i] >= '0' && val[i] <= '9')
{
count++;
}
}
printf("the count is %d\n\nand the size is %d\n", count, size);
while(count != size) ///input check to make sure user is inputting correct values.
{
//repeat
count = 0;
val = ReadLine();
size = strlen(val);
for(i = 0; i < size; i++)
{
if((val[0] == '+' && i == 0 ) || (val[0] == '-' && i == 0)){
//printf("check\n" );
count++;
i++;
}
if(val[i] >= '0' && val[i] <= '9')
{
//printf("%c\n", val[i]);
count++;
}
}
printf("count: %d\nsize: %d\n", count,size);
}
char numb[size-1];
if(val[0] == '+')
{
//char *fin = (char*)malloc(sizeof(char) * size - 1);
for(i = 1; i < 2; i++)
{
strcat(numb,&val[i]);
count++;
break;
}
printf("value of numb = %s\n", numb);
newVal = (char*)realloc(newVal,sizeof(size-1));
newVal = numb;
printf("Value of newVal = %s\n", newVal);
num = atoi(newVal);
printf("The string is %s", newVal);
return num;
}
else if (val[0] == '-')
{
for(i = 1; i < 2; i++)
{
strcat(numb,&val[i]);
break;
count++;
}
printf("value of numb = %s\n", numb);
newVal = (char*)realloc(newVal,sizeof(size-1));
newVal = numb;
printf("Value of newVal = %s\n", newVal);
num = -1 * atoi(newVal);
printf("the num is%d\nstring is : %s",num, numb);
return num;
}
//now convert that string to integer whether its plus or negative.
num = atoi(val);
return num;
This is the input that im using and this is what it prints back.
Please enter a value
-1248
the count is 5
and the size is 5
value of numb = 1248
Value of newVal = 1248
the num is 0
string is : 1248
The value you put was: 0

segmentation fault in array search C

I have this program that receives a char array with a number of messages bounded by tags. These "tags" are a sequence of chars located randomly within the char array.
Here is an example: given a char array: {'a','s','t','1','m','s','g','e','x','1','r','s','t','1','s','t','1','s','s','g','e','x','1','z'};. the tag "st1" indicates the beginning of a message which contains every char until a sequence of "ex1" is found, which is a tag for the end of the message, and it keeps searching the array for the next sequence of "st1" indicating the beginning of a new message. In this example, the messages are: "msg",and"st1ssg".
Here is my program - I keep getting a segmentation fault:
int main(int argc, char const *argv[])
{
char array[] = {'a','s','t','1','m','s','g','e','x','1','r','s','t','1','s','t','1','s','s','g','e','x','1','z'};
int state = 0;
int found = 0;
int i,j;
int msgStartIndex;
int msgEndIndex;
while(array[i]){
if((array[i] == 's' && state == 0) || (array[i] == 't' && state == 1) || (array[i] == '1' && state == 2) ){
state++;
if(!found && state == 3){
msgStartIndex = i+1;
found = 1;
}
}
else if(!found && (array[i] = 't' && state == 2))
state = 2;
else if(!found)
state = 0;
if((array[i] == 'e' && state == 3) || (array[i] == 'x' && state == 2) || (array[i] == '1' && state == 1) ){
state--;
if(found && state == 0){
found = 0;
msgEndIndex = i-3;
for(j=msgStartIndex; j < msgEndIndex+1; j++)
printf("%c",array[j]);
printf("\n");
}
}
else if(found && (array[i] == 'e' ) && (state == 2 || state == 1))
state = 2;
else if(found)
state = 3;
i++;
}
return 0;
}
You never bothered initializing your loop counter:
int i,j;
while(array[i]){
so you just start using whatever random garbage is in i to begin with. If that garbage happens to be bigger than the length of the array, boom goes your program.
Variable I was notr initialized and moreover the array is not zero-terminated.
int i,j;
/...
while(array[i]){
So the loop has undefined behavior.
You could keep a string in the array and use standard function strstr declared in header <string.h> to find the starting and ending tags.

CS50 - Credit Card Assignment; Segmentation fault

Still working on it but when I try to run the program I keep getting the error. I'm very new to programming so can't even see any issues at this point.
This is an assignment for the CS50 course; called credit card.
Also any constructive comments would be highly appreciated :)
Code is below.
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
int main(int argc, string argv[])
{
int n = 0; //n is length of card number
int i = 0; //i is the digit
int m = 0;
int p = 0;
string s = 0;
do
{
printf("Card Number: \n");
string s = GetString(); //card number
n = strlen(s);
printf("%s\n", s);
for (i = 0; i<n; i++)
{
if (i %2 == 0)
{
m = ((s[i] - '1')*2);
if (m < 10)
{
p = p + m; //p is product m is numerical value
}
else
{
p = 1 + p + (m -10);
}
}
else
{
p = p + (s[i] - '1');
}
}
if (p % 10 ==0)
{
if (n == 15 && s[1] == 3 && (s[2] == 4 | s[2] == 7))
{
printf("AMEX\n");
}
if (n == 16 && s[1] == 5 && (s[2] == 1 | s[2] == 2 | s[2] == 3 | s[2] == 4 | s[2] == 5))
{
printf("MASTERCARD\n");
}
if ((n == 3 | n==16) && s[1] == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
}
// while ();
}
Try removing the first declaration of string.
Also, I see that the while condition in the do-while loop is commented out. If it is meant to be used for the input though, the for loop which iterates over the string to analyze the number shouldn't be included in it. The do-while loop should terminate after the input is received and the program should then progress to the for loop.

Resources