command gets stuck for some reason - c

I am trying to input basic ip address from the user, but my command gets stuck here in the scanf and nothing after that is executed.
int ip1,ip2,ip3,ip4;
scanf("%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4);
printf("Here");
So, basically "Here" is never printed and the command scanf never gets over?
#include <stdio.h>
#include<math.h>
int main(void) {
char input;
char rep = 'r';
char quit = 'q';
char first = '1';
char second = '2';
input = rep;
while( input != quit) {
printf("What type of conversion do you want? \n");
printf("Enter 1 for 32-bit number to dot-decimal conversion, 2 for the inverse of operation: ");
char val;
scanf(" %c", &val);
if( val == first) {
} else if( val == second) {
printf("\nEnter dot-decimal IP address:");
int ip1,ip2,ip3,ip4;
scanf(" %d.%d.%d.%d", &ip1,&ip2,&ip3,&ip4);
printf("Here");
unsigned int ip = 0,c,k,counter = 31;
for(c = 7; c >= 0; c--) {
k = ip1 >> c;
if(k & 1) {
int temp = 2,i;
for(i = 0; i < counter;i++) {
temp *= 2;
}
ip += temp;
counter--;
}
}
for(c = 7; c >= 0; c--) {
k = ip2 >> c;
if(k & 1) {
int temp = 2,i;
for(i = 0; i < counter;i++) {
temp *= 2;
}
ip += temp;
counter--;
}
}
for(c = 7; c >= 0; c--) {
k = ip3 >> c;
if(k & 1) {
int temp = 2,i;
for(i = 0; i < counter;i++) {
temp *= 2;
}
ip += temp;
counter--;
}
}
for(c = 7; c >= 0; c--) {
k = ip4 >> c;
if(k & 1) {
int temp = 2,i;
for(i = 0; i < counter;i++) {
temp *= 2;
}
ip += temp;
counter--;
}
}
printf("%u is the IP Address",ip);
}
printf("\n \n Enter r to repeat, q to quit:");
scanf(" %c",&input);
}
return 0;
}
This is the exactly what i was doing. It gets stuck on when i try to get the IP Address in decimal notation.

I have analyzed your code after update (full code) and found that problem not in the input with scanf but in the for loops that are executed after data is obtained.
Look at that loop:
unsigned int ip = 0,c,k,counter = 31;
for(c = 7; c >= 0; c--) {
k = ip1 >> c;
if(k & 1) {
int temp = 2,i;
for(i = 0; i < counter;i++) {
temp *= 2;
}
ip += temp;
counter--;
}
}
and particularly at for(c = 7; c >= 0; c--) taking into account that c is of type unsigned int... I see that this loop is INFINITE because decrement makes from 0 new positive value UINT_MAX (see limits.h).

Related

Each function works, but not together

i have string like "1111 1010 101010" and i have two functions
int getFirstNumber(char *a){
char *p = strtok(a," ");
char str[strlen(p)];
for (int i = 0; i < strlen(p); ++i){
str[i] = p[i];
}
return getBin(str);
}
int getThirdNumber(char *a){
char *p = strtok(a," ");
int k = 0;
while (p != NULL){
p = strtok(NULL," ");
if (k == 1){
break;
}
k +=1;
}
char str[strlen(p)-1];
for (int i = 0; i < strlen(p) - 1; ++i){
str[i] = p[i];
}
return getBin(str);
}
getBin
int getBin(char *a){
int k = 1;
int res;
for (int i = strlen(a) - 1; i >= 0;i -=1){
if (a[i] == '1'){
res += k;
}
k *= 2;
}
return res;
}
The problem is if i use getFirstNumber or use getThirdNumber alone, it works, but together i have Segmentation Fault. What is wrong,

C program not running properly on raspberry pi

I'm currently designing a hemming code. This code works perfectly on my computer but when I port it over to my pi, it just does not work properly. I have no idea why and I am pretty new at C and the raspberry pi. Any help would be greatly appreciated.
Below is my full code:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
int main(void){
int bitLen, errorLoc;
printf("\nLength of the data bits: ");
scanf("%d", &bitLen);
char binStr[ bitLen ], binStrErr[ bitLen ];
printf("Data stream without error: ");
scanf("%s", &binStr);
if(strlen(binStr) > bitLen || strlen(binStr) < bitLen)
{
printf("\nLength of data stream given does not match stated input length!");
return 0;
}
printf("Location of data bit that has error: ");
scanf("%d", &errorLoc);
if(errorLoc > bitLen)
{
printf("\nValue given is bigger than the input length!");
return 0;
}
//Number Of Check Bits Needed
int rBit = 1;
while (pow(2, rBit) < (bitLen + rBit + 1))
{
rBit = rBit + 1;
}
int checkBitsArr[rBit];
int checkBitsErrArr[rBit];
//Actual size of array
bitLen = bitLen + rBit;
int binNum[bitLen];
int binNumErr[bitLen];
int size = sizeof(binNum) / sizeof(binNum[0]);
int binNumPos = size;
printf("\nData stream: ");
//Flipping the error bit and storing into another string
printf("\nOriginal data stream: ");
for (int i = 0; i < strlen(binStr); i++){
printf("%c", binStr[i]);
if(i == (strlen(binStr)) - errorLoc){
int temp = ((binStr[i] - '0') == 0) ? 1 : 0;
binStrErr[i] = temp + '0';
}
else{
binStrErr[i] = binStr[i];
}
}
printf("\nData stream with error: ");
for (int i = 0; i < strlen(binStr); i++){
printf("%c", binStrErr[i]);
}
//Filling in the bits into two arrays: One is the correct data stream and one with error
for (int i = strlen(binStr); i >= 0; i--)
{
binNum[binNumPos] = binStr[i] - '0';
binNumErr[binNumPos] = binStrErr[i] - '0';
binNumPos--;
}
printf("\n\n");
//Moving bits to left to make space
int position = 1;
for (int i = size - 1; i >= 0; i--)
{
if ((position & (position - 1)) == 0)
{
for (int c = 0; c <= i; c++)
{
binNum[c - 1] = binNum[c];
binNumErr[c - 1] = binNumErr[c];
}
binNum[i] = 33;
binNumErr[i] = 33;
}
position++;
}
//Settings check bits into place
position = 1;
int checkBitIndex = 0;
for (int i = size - 1; i >= 0; i--)
{
//Get check bit position
if ((position & (position - 1)) == 0)
{
int temp = 0;//number of 1s in relation to the check bit
int tempErr = 0;
int maxNum = (i - position) + 1;
if (maxNum < 0)
maxNum = maxNum + (-1 * maxNum);
//first part of check
while (maxNum < i)
{
if (binNum[maxNum] == 1)
{
temp++;
}
if (binNumErr[maxNum] == 1)
{
tempErr++;
}
maxNum++;
}
int startNum = (i - position) + 1;
//If the start number is less than zero, make it zero
if (startNum < 0)
startNum = startNum + (-1 * startNum);
//Skip check method. Get the next set of check values in relation to the current check bit
for (int x = startNum - (position * 2); x >= 0; x = x - (position * 2))
{
int k = 0;
while (k < position)
{
if (binNum[x + k] == 1)
{
temp++;
}
if (binNumErr[x + k] == 1)
{
tempErr++;
}
k++;
}
}
//Set the value of check bit
binNum[i] = (temp % 2 == 0) ? 0 : 1;
binNumErr[i] = (tempErr % 2 == 0) ? 0 : 1;
//Replace the current value with the correct checkbit
checkBitsArr[checkBitIndex] = binNum[i];
checkBitsErrArr[checkBitIndex] = binNumErr[i];
temp = 0;
tempErr = 0;
checkBitIndex++;
}
position++;
}
printf("\nSEC code: ");
printf("\nOriginal data stream: ");
for (int i = 0; i < size; i++)
{
printf("%d", binNum[i]);
}
printf("\nData stream with error: ");
for (int i = 0; i < size; i++)
{
printf("%d", binNumErr[i]);
}
printf("\n\n");
int checkIndex = (int)pow(2, rBit - 1);
printf("\n\nCheckbits of data bits without error: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
printf("C%d: %d ", checkIndex, checkBitsArr[i]);
checkIndex = checkIndex/2;
}
checkIndex = (int)pow(2, rBit - 1);
printf("\n\nCheckbits of data bits with error: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
printf("C%d: %d ", checkIndex, checkBitsErrArr[i]);
checkIndex = checkIndex/2;
}
checkIndex = (int)pow(2, rBit - 1);
int posError = 0;
printf("\n\nSyndrome code: \n");
for (int i = checkBitIndex - 1; i >= 0; i--)
{
int x = checkBitsErrArr[i] ^ checkBitsArr[i];
if(x == 1){
posError += checkIndex;
}
printf("C%d: %d ", checkIndex, x);
checkIndex = checkIndex/2;
}
printf("\n\n");
printf("\nPosition of error: %d\n\n", posError);
// printf("\n\n");
return 0;
}
These are the inputs for the scanf:
Length of the data bits: 16
Data stream without error: 0011001100110011
Location of data bit that has error: 8
Below are my results on both computer and pi:
Computer result (correct):
Pi result (wrong):
Looks like you have far more than just one problem, but let's just start with the first one:
char binStr[ bitLen ], binStrErr[ bitLen ];
The string you are requesting next contains not just the 16 bytes you get as input, but also an additional sentinel character as the 17th character.
So at this point you already had 2 buffer overflows, which you can already see nicely in the output from the Pi. The same buffer overflow also occurs in the first example, except the memory layout is different enough so that it doesn't yield visible artifacts.
for (int c = 0; c <= i; c++)
{
binNum[c - 1] = binNum[c];
binNumErr[c - 1] = binNumErr[c];
}
Here comes the next buffer overflow, respectively actually an underflow this time. You are writing to binNum[-1] which is a memory location outside of the memory binNum is pointing to.
Anyway, a buffer overflow means the behavior of your program is undefined.
Get used to valgrind or similar tools for checking your code for undefined with regard to such errors.

Convert number to binary and hex in C

I want to a write a program that converts a number to binary and hex.I tried to do this but It gives me the wrong result
int n, c, k;
int t = 0;
int binary[8];
for (c = 31; c >= 0; c--) {
k = num >> c;
if (k & 1) {
printf("1");
int binary[t] = 1;
} else {
printf("0");
int binary[t] = 0;
}
++t;
}

C language - operation replaces mutiple array elements instead of one

I am in the process of creating hangman in C language, but there is one problem that I cannot quite grasp. When a user correctly guesses one of the letters that the word that is being guessed has, the program replaces all of previously guessed letters to the one user just put. What is the source of this problem?
#include<stdio.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int x = 0, isCompleted, matchFound, numberOfTries = 7;
char letterGuess[1];
int randomIndex = rand()%14;
const char *wordArray[14];
const char *guessedWord[10];
const char *usedLetters[17];
for (int k = 0; k < 10; k++) {
guessedWord[k] = "_";
}
wordArray[0] = "butonierka";
wordArray[1] = "centyfolia";
wordArray[2] = "chiroplast";
wordArray[3] = "cmentarzyk";
wordArray[4] = "chrustniak";
wordArray[5] = "budowniczy";
wordArray[6] = "cholewkarz";
wordArray[7] = "cornflakes";
wordArray[8] = "brzydactwo";
wordArray[9] = "germanofil";
wordArray[10] = "lichtarzyk";
wordArray[11] = "lutowniczy";
wordArray[12] = "mikrocysta";
wordArray[13] = "tryskawiec";
const char *wordToGuess = wordArray[randomIndex];
for(int i = 0; i < 10; i++) {
printf(" %s ", guessedWord[i]);
}
printf("\n");
while(numberOfTries != 0 && isCompleted != 10) {
matchFound = 0;
isCompleted = 0;
printf("Please give a lowercase letter\n");
printf("Left tries: %d\n", numberOfTries);
scanf("%s", &letterGuess);
for (int z = 0; z < 17; z++) {
if (usedLetters[z] == letterGuess[0]) {
matchFound = 1;
}
}
if (letterGuess[0] >= 'a' && letterGuess[0] <= 'z' && matchFound == 0) {
usedLetters[x] = letterGuess[0];
x++;
for (int j = 0; j < 10; j++) {
if (letterGuess[0] == wordArray[randomIndex][j])
guessedWord[j] = letterGuess;
matchFound = 1;
}
}
if (matchFound == 0) {
numberOfTries--;
}
for(int z = 0; z < 10; z++) {
printf(" %s ", guessedWord[z]);
}
printf("\n");
} else {
if (matchFound == 1) {
printf("You've already given such letter!!\n");
} else {
printf("Wrong input, please try again!\n");
}
}
for (int k = 0; k < 10; k++) {
if (guessedWord[k] != "_") {
isCompleted++;
}
}
if (isCompleted == 10) {
printf("You have correctly guessed a word! Congrats!!\n");
}
printf("\n\n");
}
printf("The word was: %s\n", wordArray[randomIndex]);
printf("Game over!!\n");
}
The problem is that you're storing letterGuess, rather than individual characters. So each time letterGuess is updated with a new guess, all references to it change. Also, letterGuess is too short, leaving no room for the terminating null character.
The best solution is to make letterGuess a char (or an int), not an array, and to make guessedWord a char [] rather than a char *[]. There is no reason to use strings for single characters. That will solve the string-sharing problem.

C program palindrome game

I'm new in c programming and i'm trying to make a palindrome game. I've given the code below but there is some mistake I'm making and doesn't run can you please give me a hand. Thank you.
The point of the game is to give number to an array, then change with the keys a,d,x,w and try to make it palindrome.
If there is any error can u please give me some advice ?
This is pal.c
#include <stdio.h>
#include "visible.h"
//--------------------------------------------------
// is_pal
//--------------------------------------------------
void print_status(int a[], int* p, int num_mov);
int is_pal(int a[])
{
int b[6];
int i, j;
j = 0;
for (i = 5; i >= 0; i--)
{
b[j] = a[i];
j++;
}
for (i = 0; i <= 5; i++)
{
if (a[i] != b[i]) {
return 0;
}
}
return 1;
}
//--------------------------------------------------
// process_movement
//--------------------------------------------------
void process_movement(int a[], int* p, int num_mov, char c)
{
char d;
d=c;
if(d == 'd')
{
p = a+1;
num_mov++;
print_status(a,p,num_mov);
}
else if(d == 'a')
{
p = a-1;
num_mov++;
print_status(a,p,num_mov);
}
else if(d == 'x')
{
p = malloc(6*sizeof(int));
a = p-1;
num_mov++;
}
else if(d == 'w')
{
p = malloc(6*sizeof(int));
a = p+1;
num_mov++;
}
}
//--------------------------------------------------
// print_status
//--------------------------------------------------
void print_status(int a[], int* p, int num_mov)
{
printf("Number = ");
int i;
for( i = 0; i < 6; i++)
{
printf("%d ", a[i]);
}
printf("\n Number moves = ");
printf("%d", num_mov);
//printf("\n ","%s%", "Pointer is at position ");
printf("%d", *p);
printf("\n");
}
void user_game_palindrome(int pal_num)
{
int a[5];
int i,num_mov;
num_mov = 0;
i = 5;
while (pal_num != 0) {
a[i] = pal_num % 10;
pal_num = pal_num / 10;
i--;
}
int *p = a;
while (is_pal(a) == 1)
{
char c;
print_status(a,p,num_mov);
c = ask_for_command();
process_movement(a,p,num_mov,c);
}
}
This is ex1.c
#include "pal.h"
int main() {
int pal_num = 123342;
user_game_palindrome(pal_num);
return 0;
}
visible.c
#include "visible.h"
#include "conio.h"
//--------------------------------------------------
// gen_num
//--------------------------------------------------
int gen_num(int lb, int ub) {
int num = (rand() % (ub - lb)) + lb;
return num;
}
/* Note: Do not forget to include the following instruction at the beginning of your main() method:
srand(time(NULL));
*/
//--------------------------------------------------
// my_getchar
//--------------------------------------------------
char my_get_char() {
char my_char;
int b = 0;
char dummy_char;
my_char = getchar();
while (b == 0) {
dummy_char = getchar();
if (dummy_char == '\n')
b = 1;
}
return my_char;
}
this is the visible.c ( my teacher told me to include it)
Your conversion from int to array is wrong
for (i = 0; i < 4; i++) {
a[i] = pal_num%10;
pal_num = pal_num % 10;
}
Here, why would this loop end when i is 4. It should go till pal_num is 0. And pal_num = pal_num % 10; should be pal_num = pal_num / 10;
Try something like
i = 0;
while (pal_num != 0) {
a[i] = pal_num % 10;
pal_num = pal_num / 10;
i++;
}
NOTE: Be aware, that this would essentially reverse your int and store in the array.
There's a lot going wrong in your code and you still haven't fixed many things which have been pointed out by others.
as to remove the unnecessary creating of the array b, is_pal can be defined as:
int is_pal(int a[])
{
int i;
for (i = 0; i < 3; ++i)
{
if (a[5-i] != a[i])
return 0;
}
return 1;
}
process_movement doesn't have a case where d == 'w'
user_game_palindrome should have the while loop checking (is_pal(a) == 0)
And you should apply the changes that were suggested by #Haris

Resources