C Using array values erases array - c

I am confused, when i use array values to assign another array values. the original array deletes the values used
int main(int argc, char *argv[]) {
char original[ORIGINAL_SIZE];
int isbn[ISBN_SIZE];
int index = 0;
int code;
int weight = 10;
int weightedValue;
int weightedSum = 0;
printf("Enter an ISBN to validate: ");
validateISBNArray(original);
while(index < ORIGINAL_SIZE){
if(original[index] != '-'){
if(original[index] == 'x' || original[index] == 'X') isbn[index] = 10;
else if(original[index] == 0) isbn[index] = 0;
else isbn[index] = original[index]-48;
code = isbn[index];
//printf("%d", code);
weightedValue= code*weight;
weight--;
weightedSum += weightedValue;
}
index++;
}
printf("%s",original);
if(weightedSum%11==0) printf("The ISBN %s, is VALID", original);
else printf("The ISBN %s, is NOT VALID", original);
return 0;
}
validateISBNArray has no effect on original array
this is the code for the not affecting function
void validateISBNArray(char array[]){
int index = 0;
int countDigits = 0;
int value = 0;
clearArray(array, ORIGINAL_SIZE);
scanf("%s",array);
while(index < ORIGINAL_SIZE){
//printf("%d %c %d\n", index, array[index], countDigits);
if(((array[index]-48) >= 0 && (array[index]-48) <= 9) || (array[index] == 'x'|| array[index] == 'X')) {
countDigits++;
index++;
}
else if(array[index] == '-' || array[index] == 0) index++;
else{
printf("INVALID CHARACTER %d = %c. Please Enter Digits Or/And Hyphens Only: ", index, array[index]);
index = 0;
countDigits = 0;
clearArray(array, ORIGINAL_SIZE);
scanf("%s",array);
}
if(index == ORIGINAL_SIZE && countDigits != 10){
printf("INVALID NUMBER OF DIGITS %d. Please Enter 10 Digits: ", countDigits);
index = 0;
countDigits = 0;
clearArray(array, ORIGINAL_SIZE);
scanf("%s",array);
}
}
//printf("%s", array);
}

Ok I fixed it removing the need for the isbn array
int main(int argc, char *argv[]) {
char original[ORIGINAL_SIZE];
int isbn[ISBN_SIZE];
int index = 0;
int code;
int weight = 10;
int weightedValue;
int weightedSum = 0;
printf("Enter an ISBN to validate: ");
validateISBNArray(original);
while(index < ORIGINAL_SIZE){
if(original[index] != '-'){
if(original[index] == 'x' || original[index] == 'X') code = 10;
else if(original[index] == 0) code = 0;
else code = original[index]-48;
weightedValue = code*weight;
weight--;
weightedSum += weightedValue;
}
index++;
}
if(weightedSum%11==0) printf("The ISBN %s, is VALID", original);
else printf("The ISBN %s, is NOT VALID", original);
return 0;
}

Related

Searching an Array of Strings from User Input in C

I've got this homework assignment where we get the user to enter the amount of lines of strings they desire, they then proceed to enter them which gets stored in a 2D Array (thus creating an array of strings). Then a switch case menu will be displayed which should
Search a character entered by the user, returns the amount of times the character occurred in the array
Search a word entered by the user, returns the amount of times the word occurred in the array
Have the user enter a specified word length and return the amount of times words of the specified length occur.
I have a couple problems with my code. The program runs without errors from the compiler. The searchByCharacter function works fine but the searchByWord only returns a value of 0 regardless of any word inputted and nothing happens after I input a number for the searchByLength function. The program freezes after I enter a length once I select the searchByLength function. I've been at this for a while and I don't know where I'm going wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 80
#define MAX_LINES 10
#define WORD_LENGTH 20
void readText(char text[][MAX_LINE_LENGTH], int n)
{
int i;
printf("Enter %d number of lines:\n", n);
for(i = 0; i < n; i++)
{
scanf(" %[^\n]s", text[i]);
}
}
int searchByCharacter(char text[][MAX_LINE_LENGTH], int n, char c)
{
int i, charCount = 0, j = 0;
for(i = 0; i < n; i++)
{
j = 0;
while(text[i][j] != '\0')
{
if(text[i][j] == c)
{
charCount++;
}
j++;
}
}
return charCount;
}
int searchByWord(char text[][MAX_LINE_LENGTH], int n, char * keyword)
{
int i, wordCount = 0;
for(i = 0; i < n; i++)
{
int j = 0;
int lengthOfWord = 0;
char wordCheck[WORD_LENGTH];
char * currentLine = text[i];
while(currentLine[j] != '\0')
{
if (currentLine[j] == ' ' || currentLine[j] == '\n' || currentLine[j] == ',' || currentLine[j] == '.' ||
currentLine[j] == ';')
{
wordCheck[lengthOfWord] = '\0';
int matchingWord = strcmp(wordCheck, keyword);
if(matchingWord == 0)
{
wordCount++;
}
lengthOfWord = 0;
j++;
continue;
}
wordCheck[lengthOfWord] = currentLine[n];
lengthOfWord++;
j++;
}
}
return wordCount;
}
int searchByLength(char text[][MAX_LINE_LENGTH], int n, int wordLen)
{
int i, lengthCount = 0;
for(i = 0; i < n; i++)
{
int lengthOfWord = 0;
int j = 0;
char * currentLine2 = text[i];
while(currentLine2[j] != '\0')
{
if (currentLine2[j] == ' ' || currentLine2[j] == '\n' || currentLine2[j] == ',' || currentLine2[j] == '.' ||
currentLine2[j] == ';')
{
if(lengthOfWord == wordLen)
{
lengthCount++;
}
lengthOfWord = 0;
n++;
continue;
}
lengthOfWord++;
n++;
}
}
return lengthCount;
}
int main(void)
{
char textInput[MAX_LINES][MAX_LINE_LENGTH];
printf("Enter number of lines (<10): ");
int textLines = 0;
scanf("%d", &textLines);
while(textLines < 1 || textLines > 10)
{
printf("Invalid Input.\n");
printf("Enter number of lines (<10): ");
scanf("%d", &textLines);
}
if(textLines >= 1 && textLines <= 10)
{
readText(textInput, textLines);
int menuActive = 1;
while(menuActive)
{
printf("\nText Analysis\n----\n");
printf("1-Search By Character\n2-Search By Word\n3-Search By Length\n0-Quit\nPlease enter a selection: ");
int selection;
scanf("%d", &selection);
switch(selection)
{
case 0:
menuActive = 0;
break;
case 1:
printf("Selected 1\n");
printf("Enter a character to search: ");
char characterSearch;
scanf(" %c", &characterSearch);
int characterwordCount = searchByCharacter(textInput, textLines, characterSearch);
printf("\nNumber of occurence of %c = %d", characterSearch, characterwordCount);
break;
case 2:
printf("Selected 2\n");
printf("Enter a word to search: ");
char wordSearch[MAX_LINE_LENGTH];
scanf(" %s", wordSearch);
int lengthwordCount = searchByWord(textInput, textLines, wordSearch);
printf("\nNumber of occurence of %s = %d", wordSearch, lengthwordCount);
break;
case 3:
printf("Selected 3\n");
printf("Enter search length: ");
int wordLength;
scanf(" %d", &wordLength);
int wordLengthwordCount = searchByLength(textInput, textLines, wordLength);
printf("Number of words with length %d = %d", wordLength, wordLengthwordCount);
break;
default:
printf("Invalid Input.\n");
}
}
printf("You Have Quit!\n");
}
return 0;
}

I am getting a _\377 in my output

I have a school assignment to make a hangman game. The game works how I want it to except for one small glitch. If the user entered word is 4 letters or less, the hidden word is displayed with an extra "_\377" at the end. When the user entered word is 5 letters or more, then there is no glitch. I am hoping that someone would be kind enough to help me trouble shoot the problem. Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int letterfinder(char string[], char a, int vari)
{
int length = strlen(string);
int i = vari;
int val = 0;
while( i <= length && val != 1)
{
if( string[i] == a)
{
val = 1;
}
i++;
}
if( val == 0)
{
return 100;
}
else
{
return i;
}
}
int main()
{
char inWord[] = "1111111111111111111111111111";
char outWord2[] = "1111111111111111111111111111";
char guess;
int gameover = 0;
int trys = 10;
int vari = 0;
printf("Please enter a word: ");
gets(inWord);
printf("%s\n", inWord);
printf(" \n");
printf(" \n");
printf(" \n");
printf(" \n");
printf(" \n");
printf(" \n");
int i2 = 0;
int j2 = 0;
int i3 = 0;
i2 = strcspn(inWord, outWord2);
char outWord[80];
while(i3 < i2)
{
outWord[i3] = '1';
i3++;
}
while(j2 < i2)
{
outWord[j2] = '-';
j2++;
}
puts(outWord);
while(gameover != 1 )
{
printf("What is your guess: ");
scanf("%s", &guess);
vari = 0;
if(letterfinder(inWord, guess, vari) == 100)
{
printf("Wrong!");
trys--;
printf("You have %d attempts left\n", trys);
if(trys == 0)
{
gameover = 1;
printf("You ran out of attempts. Game over\n");
}
}
else
{
outWord[(letterfinder(inWord, guess, vari) - 1)] = guess;
vari = (letterfinder(inWord, guess, vari));
while(letterfinder(inWord, guess, vari) != 100)
{
outWord[(letterfinder(inWord, guess, vari) - 1)] = guess;
vari = letterfinder(inWord, guess, vari);
}
puts(outWord);
}
int value = 0;
i3 = 0;
while( i3 <= i2)
{
if( outWord[i3] == '-')
{
value = 1;
}
i3++;
}
if(value != 1)
{
printf("Congratulations, you have guessed the word!\n");
gameover = 1;
}
}
return 0;
}
Your code has Undefined Behaviour. In the cases it "works" it is only by chance/luck. char guess; scanf("%s", &guess); That causes memory corruption as you are writing a string to a variable that can only hold a single char. Even a single letter guess will require two characters to store as all C strings are NUL terminated.
– kaylum

remove element from pointer array in C

I'm trying to figure out why I cannot delete elements from the dict array. Could somebody help me out? The function removeWord is working as it is supposed to when removing the last added word, but not when trying to remove some other word.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUMBER_OF_WORDS 11
int clear(){
while(getchar()^'\n');
return 0;
}
int numberOfWordsInDict(char **dict){
int i = 0;
int c1 = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
if (dict[i] != 0){
c1++;
}
}
return c1;
}
void addWord(char **dict, char *word){
int c1 = numberOfWordsInDict(dict);
char *word1;
if (c1 >= 0 && c1 < 10){
word1 = (char*) malloc(sizeof(char)*(strlen(word)+1));
dict[c1] = word1;
strncpy(dict[c1], word, strlen(word));
dict[c1][strlen(word)] = '\0';
} else if (c1 >= 10){
printf("Dictionary is already full!\n");
}
}
void printDict(char **dict){
int i = 0;
int c1 = numberOfWordsInDict(dict);
printf("Dictionary:\n");
if (c1 == 0){
printf("The dictionary is empty.\n");
} else if (c1 > 0 && c1 <= 10){
while (dict[i] != NULL){
printf("- %s\n", dict[i]);
i++;
}
}
}
void removeWord(char **dict, char *word){
int i = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; i++){
if (strncmp(dict[i], word, strlen(word)+1) == 0){
dict[i] = 0;// can only delete the last element of dict properly.
break;
}
}
}
int main(){
char *dict[MAX_NUMBER_OF_WORDS] = {};
char word[1024] = {};
char command;
while(1){
printf("Command (a/p/r/q): ");
while(scanf("%s", &command) == 1){
break;
}
;
clear();
if (command == 'a'){ // add word
scanf("%[^\n]s", &word);
clear();
addWord(dict, word);
} else if (command == 'p'){ // print dict
printDict(dict);
} else if (command == 'r'){ // remove word
printf("Remove a word: ");
scanf("%[^\n]s", &word);
clear();
removeWord(dict, word);
} else if (command == 'q'){ // quit
break;
}
}
int i = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; i++){
free(dict[i]);
}
return 0;
}
example input:
a
dog
a
cat
a
apple
case 1:
r
apple
p
// output =
Dictionary:
- dog
- cat
a
uniform
p
// output =
Dictionary:
- dog
- cat
- uniform
// works fine
case 2
r
cat
p
// output =
Dictionary:
- dog
a
book
p
// output =
Dictionary:
- dog
// doesn't work as expected
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUMBER_OF_WORDS 11
int clear(){
while(getchar()^'\n');
return 0;
}
int numberOfWordsInDict(char **dict){
int c1 = 0;
for(int i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
if (dict[i] != 0){
c1++;
}
}
return c1;
}
int vacancy(char **dict){
for(int i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
if (dict[i] == 0){
return i;
}
}
return -1;
}
void addWord(char **dict, char *word){
int c1 = vacancy(dict);//It is not possible to use the registration number as an additional index.
if (-1 != c1){
dict[c1] = malloc(strlen(word)+1);
strcpy(dict[c1], word);
} else {
printf("Dictionary is already full!\n");
}
}
void printDict(char **dict){
int c1 = numberOfWordsInDict(dict);
printf("Dictionary:\n");
if (c1 == 0){
printf("The dictionary is empty.\n");
} else {
for(int i = 0; i < MAX_NUMBER_OF_WORDS; ++i){
if(dict[i])
printf("- %s\n", dict[i]);
}
}
}
void removeWord(char **dict, char *word){
for(int i = 0; i < MAX_NUMBER_OF_WORDS; i++){
if (strcmp(dict[i], word) == 0){
free(dict[i]);//need free
dict[i] = 0;// can only delete the last element of dict properly.
break;
}
}
}
int main(){
char *dict[MAX_NUMBER_OF_WORDS] = { NULL };
char word[1024] = { 0 };//forbids empty initializer braces
char command;
while(1){
printf("Command (a/p/r/q): ");
scanf("%c", &command);//%s buffer over run
clear();
if (command == 'a'){ // add word
scanf("%[^\n]", word);
clear();
addWord(dict, word);
} else if (command == 'p'){ // print dict
printDict(dict);
} else if (command == 'r'){ // remove word
printf("Remove a word: ");
scanf("%[^\n]", word);
clear();
removeWord(dict, word);
} else if (command == 'q'){ // quit
break;
}
}
int i = 0;
for (i = 0; i < MAX_NUMBER_OF_WORDS; i++){
free(dict[i]);
}
return 0;
}
Inside printDict() use
while (i<MAX_NUMBER_OF_WORDS){
if(dict[i] != 0)
printf("- %s\n", dict[i]);
i++;
}
instead of
while (dict[i] != NULL){
printf("- %s\n", dict[i]);
i++;
}
because even if you know if there are c1 number of words, you don't know their location as in where those c1 words are present.
Also change
while(scanf("%s", &command) == 1)
to
while(scanf("%c", &command) == 1)
since command is of char type.

C simple program

I'm learning starting to learn C, so I tried to make a simple program with what I know. The program SHOULD ask for a letter, ask if you want the position of a letter in the alphabet(if so it displays "x is the y letter in the alphabet" with the suffix) and then it asks if you want the letter in binary and puts it in binary. But for some reason it doesn't work. I tried "manual debugging"(using puts() to see what doesn't work) and the class "getNumber" works but the value changes when it goes to the main class.
a returns "2686719" instead of "a is the 1st letter in the alphabet" and b returns "2b is the 2z\<<y in the alphabet".
This is the code, what did I do wrong?
#include <stdio.h>
#include <stdlib.h>
//011
int main(){
int x = 2;
char letter;
puts("Write a letter");
char temp2;
scanf("%c", &temp2);
int number;
letter = temp2;
puts("get alphabet position? y/n ");
char temp[2];
scanf("%s", temp);
char answer = temp[0];
int tempNumber2 = getNumber(letter);
if(answer == 'y'){
char suffix[3];
int number = tempNumber2;
printf("%d", number);
if (number == 1){
x = 1;
suffix[0] = "s";
suffix[1] = "t";
}else if (number < 27){
suffix[0] = "t";
suffix[1] = "h";
x = 1;
}
if (x == 1){
printf("%c is the %d", letter, number);
printf("%s in the alphabet\n", suffix);
}}else if (answer == 'n'){
x = 1;
}else if (answer != 'y' && answer != 'n'){
puts("ERROR, invalid letter");
x = 3;
};
if(x != 3){
puts("Convert to binary?");
}
return 0;
}
int getNumber(letter){
char tempLetter = letter;
int tempNumber = -1;
char alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
int i = 0;
while(i < 27){
i++;
if(tempLetter == alphabet[i]){
tempNumber = i;
tempNumber++;
printf("%d \n", tempNumber);
return tempNumber;
}
};
}
By the way, I haven't gotten to the binary part hence why it's empty.
As everyone stated in the comments your problem is that suffix's last char is not set to '\0'.
Moreover, you could getNumber in a much simpler way:
int getNumber(char letter) {
return (int)(letter - 'a') + 1;
}
Btw, you can make your code look a little better (didn't change it too much):
int main() {
char letter;
char answer;
puts("Write a letter");
scanf("%c", &letter);
getchar(); // read \n
puts("get alphabet position? y/n ");
scanf("%c", &answer);
getchar(); // read \n
if (answer == 'n') {
return 0;
}
if (answer != 'y') {
puts("ERROR, invalid letter");
return 1;
}
int number = getNumber(letter);
char suffix[3];
suffix[2] = 0;
if (number == 1) {
suffix[0] = 's';
suffix[1] = 't';
} else if (number == 2) {
suffix[0] = 'n';
suffix[1] = 'd';
} else if (number == 3) {
suffix[0] = 'r';
suffix[1] = 'd';
} else {
suffix[0] = 't';
suffix[1] = 'h';
}
printf("%c is the %d%s letter in the alphabet\n", letter, number, suffix);
puts("Convert to binary?");
return 0;
}

Replacing elements in an array

I have a problem thats giving me a huge ache.
This piece of code purpose is to fill up an array with integer values and at the same time defend against strings and etc....but it doesn't defend against duplicates, but tried I got to far as replacing the number with a new number for example
Enter 6 integers
1, 2, 2, 3, 4, 5
my code will let me replace that 2 at position 1 with another number. What I want it to do is not to repeat the same number again, for example please replace 2 at position 1. I dont want the user to enter 2 again... and I want to make it to double check the work the array if any repeating numbers exists thank you.
system("clear");
printf("\nEntering Winning Tickets....\n");
nanosleep((struct timespec[]){{1, 0}}, NULL);
system("clear");
char userInput[256];
char c;
int duplicationArray[6] = {-1, -1, -1, -1, -1, -1};
for (i = 0; i < 6; i++)
{
printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
fgets(userInput, 256, stdin);
if ((sscanf(userInput, "%d %c", &winningNumbers[i], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
printf("\nInvalid Input.\n") ;
nanosleep((struct timespec[]){{0, 350000000}}, NULL);
system("clear");
i = i - 1;
}
}
for (i = 0; i < 6 - 1; ++i)
{
min = i;
for (j = i+1; j < 6; ++j)
{
if (winningNumbers[j] < winningNumbers[min])
min = j;
}
temp = winningNumbers[i];
winningNumbers[i] = winningNumbers[min];
winningNumbers[min] = temp;
}
for (i = 0; i < 6; i++)
{
if (winningNumbers[i] == winningNumbers[i+1])
{
duplicationArray[i] = i;
duplicationCounter++;
}
else
{
duplicationCounter--;
}
}
if (duplicationCounter > -6)
{
for (i = 0; i < 6; i++)
{
int j, min, temp;
min = i;
for (j = i+1; j < 6; ++j)
{
if (duplicationArray[j] > duplicationArray[min])
min = j;
}
temp = duplicationArray[i];
duplicationArray[i] = duplicationArray[min];
duplicationArray[min] = temp;
}
for (i = 0; i < 6; i++)
{
if (duplicationArray[i] == -1)
{
zeroCounter++;
}
}
int resize = (6 - zeroCounter)+1;
for (i = 0; i <= resize; i++)
{
if (duplicationArray[i] == -1)
{
i++;
}
else if (duplicationArray[i] != -1)
{
system("clear");
printf("\nDuplicated numbers has been dected in your array. ");
printf("\nPlease replace the number %d at postion %d with another number: ", winningNumbers[duplicationArray[i]], duplicationArray[i]);
fgets(userInput, 256, stdin);
if ((sscanf(userInput, "%d %c", &winningNumbers[duplicationArray[i]], &c) != 1 || (winningNumbers[i] <= 0) || winningNumbers[i] >= 50))
{
printf("\nInvalid Input.\n") ;
nanosleep((struct timespec[]){{0, 350000000}}, NULL);
system("clear");
i = i - 1;
}
}
}
duplicationCounter = 0;
for (i = 0; i < 6; i++)
{
if (winningNumbers[i] == winningNumbers[i+1])
{
duplicationArray[i] = i;
duplicationCounter++;
}
else
{
duplicationCounter--;
}
}
printf("%d, ", duplicationCounter);
}
#include <stdio.h>
#include <stdint.h>
#define DATA_SIZE 6
int main(void){
char userInput[256];
int inputNum, winningNumbers[DATA_SIZE];
uint64_t table = 0;
int i=0;
while(i<DATA_SIZE){
printf("\nPlease enter the %d winning ticket number!(#'s must be between 1-49): ", i+1);
fgets(userInput, sizeof(userInput), stdin);
if(sscanf(userInput, "%d", &inputNum) != 1 || inputNum <= 0 || inputNum >= 50)
continue;
uint64_t bit = 1 << inputNum;
if(table & bit)
continue;
table |= bit;
winningNumbers[i++] = inputNum;
}
for(i=0;i<DATA_SIZE;++i)
printf("%d ", winningNumbers[i]);
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define DATA_SIZE 6
int inputNumberWithRangeCheck(const char *msg, const char *errMsg, int rangeStart, int rangeEnd){
char inputLine[256];
int n;
for(;;){
printf("%s", msg);
fgets(inputLine, sizeof(inputLine), stdin);
if(sscanf(inputLine, "%d", &n) != 1 || n < rangeStart || n > rangeEnd)
fprintf(stderr, "%s", errMsg);
else
return n;
}
}
int inputNumber(void){
return inputNumberWithRangeCheck(
"\nPlease enter the winning ticket number!(#'s must be between 1-49): ",
"Invalid Input.\n",
1,49);
}
int *inputArray(int *array, size_t size){
int i;
for(i=0;i<size;++i){
printf("\nInput for No.%d\n", i+1);
array[i] = inputNumber();
}
return array;
}
int **duplicateCheck(int *array, size_t size){
int **check, count;
int i, j;
check = malloc(size*sizeof(int*));
if(!check){
perror("memory allocate\n");
exit(-1);
}
//There is no need to sort the case of a small amount of data
//(Cost of this loop because about bubble sort)
for(count=i=0;i<size -1;++i){
for(j=i+1;j<size;++j){
if(array[i] == array[j]){
check[count++] = &array[i];
break;
}
}
}
check[count] = NULL;
if(count)
return check;
else {
free(check);
return NULL;
}
}
int main(void){
int winningNumbers[DATA_SIZE];
int **duplication;
int i, j;
inputArray(winningNumbers, DATA_SIZE);
while(NULL!=(duplication = duplicateCheck(winningNumbers, DATA_SIZE))){
for(i=0;i<DATA_SIZE;++i){
if(duplication[i]){
printf("\nyour input numbers : ");
for(j=0;j<DATA_SIZE;++j)
printf("%d ", winningNumbers[j]);
fprintf(stderr, "\nThere is duplicate. Please re-enter.\n");
*duplication[i] = inputNumber();
} else
break;
}
free(duplication);
}
for(i=0;i<DATA_SIZE;++i)
printf("%d ", winningNumbers[i]);
printf("\n");
return 0;
}

Resources