How can I get 4 integers from an IP address string? - c

I am trying to get 4 integers from an IP-address. For example, 12.34.56.78. A = 12, b = 34, c = 56, and d = 78. Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char ADDRESS[100];
printf("Enter IP: ");
scanf("%s", ADDRESS);
return 0;
}
How would I be able to do this?

try to use good old sscanf().
int A, B, C, D;
sscanf(ADDRESS, "%d.%d.%d.%d", &A, &B, &C, &D);
It may be a good idea to check if sscanf() returned 4 what indicates that all four numbers were correctly parsed.

if you're asked to read it as a string at first , you need to add a condition that it exists 4 points in the string
do {
count=0;
for (i=0;i<strlen(address);i++) {
if (address[i] == '.')
count++;
}
if (count > 4) {
printf("Enter IP: ");
scanf("%s", ADDRESS); }
while (!(count <= 4));
secondly using strtok can make everything easy , you have to split your string with the . caracter so it goes with something like this
char *tester;
int counter=0,a,b,c,d;
tester = strtok(address, ".");
while( tester != NULL ) {
switch (counter) {
case 0:
a=atoi(tester);
counter++;
break;
case 1:
b=atoi(tester);
counter++;
break;
case 2 :
c=atoi(tester);
counter++;
break;
case 3:
d=atoi(tester);
counter++;
break; }
tester= strtok(NULL, ".");
}

Related

C code acting weird. Sometimes, it takes input, sometimes it doesn't

I'm making a multi-feature command-line application where users have features like encrypt-decrypt a string, check string palindrome and reverse a string, and I started to write my whole code with the encrypt-decrypt feature, but apparently it is not working as expected, sometimes it encrypts/decrypts the string, the same code when executed again exits itself without taking the string input! I have even inserted the fflush(stdin), but no luck!
#include <stdio.h>
void encryptDecrypt();
// void checkPalindrome();
// void reverseWord();
void main()
{
int choice;
printf("\nWelcome to Jeel's multi-feature C App\n\n");
printf("1. Encrypt-Decrypt a word\t2. Check Palindrome\t3. Reverse a word\n\n");
printf("Enter a feature: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
fflush(stdin);
encryptDecrypt();
break;
case 2:
// checkPalindrome();
break;
case 3:
// reverseWord();
break;
default:
break;
}
}
void encryptDecrypt()
{
fflush(stdin);
char eOrD;
printf("\nWelcome to the World of Encryption & Decryption! We're so glad that you're here!\n\n");
printf("Enter 'e' if you want to encrypt a word or 'd' if you want to decrypt a word (e/d): ");
scanf("%c", &eOrD);
if (eOrD == 'e' || eOrD == 'E')
{
fflush(stdin);
char *word;
printf("\nGreat! Now enter a word to encrypt it: ");
fflush(stdin);
gets(word);
char *ptr = word;
for (int i = 0; i < sizeof(ptr); i++)
{
if (*ptr != '\0')
{
*ptr = *ptr + 7;
ptr++;
}
}
printf("\nEncrypted string is: %s, which is encrypted with the key: %d", word, 7);
}
else if (eOrD == 'd' || eOrD == 'D')
{
fflush(stdin);
char *deWord;
printf("\nGreat! Now enter a word to decrypt it: ");
gets(deWord);
char *dePtr = deWord;
for (int i = 0; i < sizeof(dePtr); i++)
{
if (*dePtr != '\0')
{
*dePtr = *dePtr - 7;
dePtr++;
}
}
printf("\nDecrypted string is: %s, which is decrypted with the key: %d\n", deWord, 7);
}
else
{
printf("Invalid input! Please try again!");
}
}
The best and most portable way to clear the stdin is using this:
void clearStream()
{
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
Also the following is incorrect, create an array instead of the pointer:
char *word;
gets(word); //word is a pointer, gets will not create a block of memory for it

if statement not taking input in strcmp string input

#include <stdio.h>
#include <conio.h>
#include <string.h>
main() {
char d[10];
int value = 0, val1, val2;
printf("Enter Day: ");
scanf("%c", &d);
val1 = strcmp(d, "sunday");
val2 = strcmp(d, "saturday");
if (val1 == 0) {
printf("AS");
value = 2;
} else
if (val2 == 0) {
value = 1;
}
switch (value) {
case 2:
printf("So sad, you will have to work");
break;
case 1:
printf("Enjoy! its holiday");
break;
default:
printf("Print valid character");
}
}
I enter code here want to input days and to get some output using switch statement but strcmp is not working in if statement
I have to use a switch statement also
if statement not recognising value.
At least this problem:
strcmp(d,"sunday") expects array d to contain a string.
d does not certainly contain a string as no null character was assigned there.
char d[10];
printf("Enter Day: ");
scanf("%c",&d); // Writes, at most, 1 character to `d`. Remainder of `d[]` is uninitialized.
Instead
if (scanf("%9s",d) == 1) {
printf("Success, read <%s>\n", d);
Tip: Consider using fgets() to read user input.
Tip: Enable all compiler warnings to save time.

Why does my number variable change after running the 'insert' function?

I have been looking at this code of mine for my schoolwork but I cannot understand why my integer variable has changed after I passed it into a function by value although I did not alter it in the function.
#include <stdio.h>
#include <stdlib.h>
void Q1();
void Q1_Remove (char **ptr_string);
void Q1_Insert (char **ptr_string, int length);
int main()
{
Q1();
return 0;
}
void Q1 () {
int number;
printf("How many characters do you want to input: ");
scanf("%d", &number);
char *string = malloc(number + 1);
printf("Input the string: ");
scanf("%s", string);
printf("The string is: %s\n", string);
int option;
do {
printf("Do you want to 1-Insert, 2-Remove or 3-Quit: ");
scanf("%d", &option);
switch (option) {
case 1:
Q1_Insert(&string, number);
break;
case 2:
Q1_Remove(&string);
break;
}
if (option == 1 || option == 2) {
printf("Resulting string: %s\n", string);
}
} while (option == 1 || option == 2);
free(string);
}
void Q1_Remove (char **ptr_string) {
(*ptr_string)++;
}
void Q1_Insert (char **ptr_string, int length) {
int curr_len = strlen(*ptr_string);
int i;
printf("length is %d and curr_len is %d", length, curr_len);
if (curr_len == length) {
for (i = curr_len - 1; i > 0; --i) {
*(ptr_string + i) = *(ptr_string + i - 1);
}
} else {
(*ptr_string)--;
}
char to_insert;
printf("What is the character you want to insert: ");
scanf(" %c", &to_insert);
**ptr_string = to_insert;
}
My terminal input and output:
How many characters do you want to input: 5
Input the string: abcde
The string is: abcde
Do you want to 1-Insert, 2-Remove or 3-Quit: 1
length is 5 and curr_len is 5
What is the character you want to insert: a
Resulting string: abcde
Do you want to 1-Insert, 2-Remove or 3-Quit: 1
length is 11212224 and curr_len is 5 // length is weird here
What is the character you want to insert:
(EDIT 2)
Removed constant for variable number and added in the declaration on the top. Edited to add in the headers!
Primarily the issue is how you are shuffling characters in the string. You are doing this:
for (i = curr_len - 1; i > 0; --i) {
*(ptr_string + i) = *(ptr_string + i - 1);
}
However, the actual string pointer is *ptr_string. Since you are using ptr_string + i, it's treating ptr_string as an array of pointers, and you are writing all over the stack memory following your string pointer defined in main. This will be what is trashing your number value, among other things.
Instead, you need to do this:
*(*ptr_string + i) = *(*ptr_string + i - 1);
Personally, I'd use array notation instead, which is far more readable:
(*ptr_string)[i] = (*ptr_string)[i - 1];
Or simply scrap the loop entirely and use memmove.

How to insert int values into matrix by using if statement with char conditioning?

I'm learning C and I'm having trouble with this situation where I need to put values inside a matrix based on user char input, here is the code:
#include <stdlib.h>
#include <stdio.h>
int main() {
int mat[2][2] = { NULL };
char sex;
printf("Insert gender (m or f):");
scanf_s("%c", &sex);
if (&sex == "m") {
mat[0][0] = 1;
}
if (&sex == "f") {
mat[0][0] = 2;
}
else{
mat[0][0] = 3;
printf("invalid\n");
}
printf("inserted: %c \n", sex);
printf("value on matrix 00: %i\t", mat[0][0]);
//printf("%i\n", mat[0][1]);
//printf("%i\t", mat[1][0]);
//printf("%i", mat[1][1]);
return 0;
}
The values at the end seem to be right but the program don't runs as I expected and I can't see my mistake, any help?
In C, operator == cannot be used to compare strings. To do so, you should use the function strcmp from string.h. In any case, what you need is not to compare strings, but to compare characters (and what you are doing is to compare an address with a string). My suggestion: scan a char instead of a string (using scanf instead of scanf_s) and change your equality tests from &var == "val" to var == 'val'. Also some tips in the code below:
#include <stdlib.h>
#include <stdio.h>
int main()
{
//name your variables properly
//initialize them immediately to avoid undefined values
//respect its types: use '\0' instead of 0 for chars, and 0 instead of NULL for ints
char gender = '\0';
int matrix[2][2] = {{0, 0}, {0, 0}};
//display accurate messages to the user
printf("Select a gender (m or f): ");
//don't scan a string if you only need a char
//always check the return of a scan
if(scanf("%c", &gender) <= 0)
{
printf("Input error\n");
return 0;
}
//switch is usually more efficient than else-ifs
switch(gender)
{
case 'm':
matrix[0][0] = 1;
break;
case 'f':
matrix[0][0] = 2;
break;
default:
printf("Invalid gender\n");
return 0;
}
printf("Selected gender: %c\n", gender);
printf("Value on matrix[0][0]: %d\n", matrix[0][0]);
return 0;
}
&sex == "m" compares the address of sex with the address of the string literal "m", which will presumably evaluate to false. This is not what you want.
You should compare the value of sex with the character literal 'm', as in:
if (&sex == "m") {
// ...
}
The same goes for &sex == "f", which should be sex == 'f'.

How to split a char* to integer tables in C

I have a char* like this "1 10 14 16"
I want to split it to integer array like 1,10,14,16...
how i do that?
I suggest using strtol in a loop, using explicitly its endptr argument, something like:
char* pc = input_string;
char* end = NULL;
while (*pc) {
long l = strtol (pc, &end, 0);
if (end == pc) break;
do_something_useful_with_the_number (l);
pc = end;
}
if you want to accumulate all the numbers in an array, replace do_something_useful_with_the_number (l); with code growing that array (probably using malloc and/or realloc ...)
I would use strtok() like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
char string[] = "1 10 14 16",
*next = NULL;
int number[10] = {0},
noOfNumbers = 0,
i = 0;
next = strtok(string, " "); /* first call must have the string and delimiters */
while ( next != NULL ) {
number[noOfNumbers++] = atoi(next);
next = strtok(NULL, " "); /* second call only the delimiters */
}
for ( i = 0; i < noOfNumbers; i++ ) {
printf("number[%d] = %d\n", i, number[i]);
}
return 0;
}
How you ensure the array of ints is big enough is left to you.
Use strtok to separate the numbers and then use atoi on each of them to convert them to integers.
http://www.elook.org/programming/c/strtok.html
int output[4];
char *input_string = "1 10 14 16";
sscanf(input_string, "%d %d %d %d", &output[0], &output[1], &output[2], &output[3]);
printf(" OUTPUT : %d %d %d %d\n", output[0], output[1], output[2], output[3]);
Above code should work
Regards
1 you will have to a strtok to get one number string at a time.
2 Then you have todo atoi to convert a number string into an int.
This needs to be done till the loop condition of strtok returns a valid string
#include <stdio.h>
///i is count *input_string[] times
///j is count temp[] times
int main() {
int i,j=0,num=0,*ptr,output;
char temp[9]={'\0'};
char *input_string[] = {"1 10 14 16 20 31 34 67 23 45 23"};
for(i=0;*(*(input_string+0)+i)!='\0';)
{
switch(*(*(input_string+0)+i))
{
case ' ':i++;break;
case '1':case '2':case '3':
case '4':case '5':case '6':
case '7':case '8':case '9':
case '0':
j=0;
while(*(*(input_string+0)+i) != ' ' || j>9 )
{
temp[j]=*(*(input_string+0)+i);
i++;j++;
}
j++;
temp[j]='\0';
output=atoi(temp);
ptr=malloc( sizeof(int) );
ptr=&output;
printf("%d ",*ptr);
break;
}
}
return 0;
}
I made small modifications.I updated the malloc (); function.May I ask whether the condition?Thank you!
#include <stdio.h>
///i is count *input_string[] times
///j is count temp[] times
///num is count output[] times
int main() {
int i,j=0,num=0;
int output[4];
char temp[9]={'\0'};
char *input_string[] = {"1 10 14 16"};
for(i=0;*(*(input_string+0)+i)!='\0';)
{
switch(*(*(input_string+0)+i))
{
case ' ':i++;break;
case '1':case '2':case '3':
case '4':case '5':case '6':
case '7':case '8':case '9':
case '0':
j=0;
while(*(*(input_string+0)+i) != ' ' || j>9 )
{
temp[j]=*(*(input_string+0)+i);
i++;j++;
}
j++;
temp[j]='\0';
output[num]=atoi(temp);
num++;
break;
}
}
for(i=0;i<4;i++)///print number
printf("%d ",output[i]);
return 0;
}
///*(*(input_string+0)+i) you can see is e.g char input_string[][];

Resources