Making y[i] a modifiable variable in C - c

I am building a program that randomly generates a password using the ascii tabe of values and can only contain one of each char. it generates a password that is 8 char long.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define SIZE 10
char Charactor(char x);
void Check(char* y);
int main()
{
char string[SIZE];//defines varriables
char* point;
point=&string[SIZE];
srand(time(NULL));
for (int i=0;i<SIZE-1;i++)//empties out the string
{
string[i]='\0';
}
for (int i=0;i<SIZE-2;i++)//randomizes a char for each space in the string
{
string[i]=Charactor(*point);
}
Check(point);/checks the string for duplicated values
printf("%s\n",string);//prints string on screen
}
char Charactor(char x)
{
int rnd=0;
rnd=rand()%2;//chooses char or number using ascii
if (rnd==0)
{
rnd=rand()%10+48;
}
else
{
rnd=rand()%26+65;
}
x=(char)rnd;
return x;
}
void Check(char* y)
{
int run=0;
for (int i=0; i<SIZE-2;i++)
{
for (int x=0; x<SIZE-2; x++)
{
if (y[i]==y[x] && run=0)
{
run++;
continue;
}
else
{
y[i]='\0';
y[i]=Charactor(*y);
}
}
}
return;
}
with those changes the code is running now I just have to figure out how to change the correct value so I dont have any duplication.

Fix:
char* point =&string[0]; //Make it to point to first element
Since your Charactor(*point); is really not doing anything based on *point and later you use Check(point); probably to start a scan from start of string.
And
if (y[i]==y[x] && run==0)
^^Use Equality check
You cannot modify a boolean outcome of y[i]==y[x] && run as zero.
Note :
However if (y[i]==y[x] && (run=0) ) wouldn't have thrown this error.

Your error seems to be that you are mistakenly setting run=0 in
if (y[i]==y[x] && run=0)
This is the part that most likely confuses your compiler. Doesn't have to do anything with Y.
Fix to:
if (y[i]==y[x] && run==0)

Related

Using OR in statements with arrays, (C)

I've been trying to make a username and password interface and I was wondering if it was possible to have an or statement within strcmp and if I could also use all values of the array within 1 string, Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int u, p;
char Iuser[50],Ipass[50];
char user[3][50] = { "user1", "user2", "user3" };
char pass[3][50] = { "pass1", "pass2", "pass3" };
printf("\n Enter your username:");
gets(Iuser);
u = strcmp(user[0|1|2], Iuser);
if (u == 0) {
printf("\n Enter your password");
scanf("%s", &Ipass);
} else {
printf("\n Invalid Username, Try Again !");
}
}
No, you can't do like that in C.
I'm stealing Aconcagua's comment about what it actually does:
user[0|1|2] first calculates 0|1|2, then accesses the array. Result of bitwise OR-ing 0, 1 and 2 is 3, though, which already is out of bounds of your user array, thus undefined behaviour
So, instead of
u=strcmp(user[0|1|2],Iuser);
if(u==0) {
You should do:
#include <stdbool.h>
bool u = strcmp(user[0], Iuser) == 0 ||
strcmp(user[1], Iuser) == 0 ||
strcmp(user[2], Iuser) == 0;
if(u) {
If the array of users is long or the number of users is not known at compile-time:
bool u = false;
for(int i = 0; i < number_of_users; ++i) {
if(strcmp(user[i], Iuser) == 0) {
u = true;
break;
}
}
if(u) {
Note: Don't use bitwise OR, |, for these comparisons. Using the logical OR, ||, enables short-circuit evaluation so that it stops testing as soon as one condition is true, just like the loop above which breaks out as soon as one condition has been found true.
strcmp cannot be used this way: user[0|1|2] evaluates to user[3], which accesses an element of the array beyond the end of the array: strcmp() will have undefined behavior when it reads from this place.
The C library does not have a generic function to locate a string in an array, so you should write:
u = strcmp(user[0], Iuser) && strcmp(user[1], Iuser) && strcmp(user[2], Iuser);
Which is quite verbose and specific.
Note that you should always ask for a password to avoid giving information about user names to an intruder, so the code should be modified as:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char Iuser[50];
char Ipass[50];
char user[3][50] = { "user1", "user2", "user3" };
char pass[3][50] = { "pass1", "pass2", "pass3" };
int nusers = sizeof(user) / sizeof(user[0]); // number of users
int u;
for (;;) {
printf("\n Enter your username:");
if (scanf("%49s", Iuser) != 1)
return 1;
printf("\n Enter your password");
if (scanf("%49s", Ipass) != 1)
return 1;
for (u = 0; u < nusers; u++) {
if (strcmp(user[u], Iuser) == 0 && strcmp(pass[u], Ipass) == 0)
break;
}
if (u < nusers)
break;
printf("\n Invalid Username and/or password, Try Again !");
}
// user has been authenticated.
// ...
return 0;
}
Note also that password should be read without echoing the characters to the terminal, which is tricky but can be achieved on unix systems via getpass:
#include <pwd.h>
#include <unistd.h>
char *getpass(const char *prompt);
Passwords should not be stored in clear text as you do, nor as encrypted text because they would be too easy to find. Computing a cryptographic hash is recommended, in addition to more advanced techniques.
You should do
u=strcmp(user[0],Iuser)!=0 && strcmp(user[1], Iuser)!=0 && strcmp(user[2],Iuser)!=0;
if(u==0) {
//User exists so ask password
because strcmp accepts only two strings to compare. If you do a OR as u said it would be something strange like bitwise operation inside char arrays, I doubt it would ever compile and we don't want to do that.
Have a good day.

how to remove certain words from a line of text in c

I got my code working to an extent, but I need some more help. If I needed to remove the word "an", from sentence: "I ate an apple whilst looking at an ape.", it only removes the first "an" and not the second, how do I repeat the loop so it deletes all "an"s? I need the final sentence, after the code has been ran, to be: "I ate apple whilst looking at ape.". That is the goal im trying to achieve
Sorry for not including the code.
Here it is:
#include "RemoveFromText.h"
#include <stdlib.h>
#include <string.h>
int findFirstSubstring(char textToChange[], char removeThis[])
{
int size = strlen(textToChange);
int subStringLength = strlen(removeThis);
for(int i=0; i<size; i++)
{
if(textToChange[i] == removeThis[0])
{
int j = 0;
while(textToChange[i+j] == removeThis[j])
{
j++;
if(j==subStringLength)
{
return i;
}
}
}
}
return -1;
}
void removeFromText( char textToChange[], char removeThis[])
{
int textLength = strlen(textToChange);
if(findFirstSubstring(textToChange, removeThis) >= 0)
{
int subStringIdx = findFirstSubstring(textToChange, removeThis);
int loopVariabele = 0;
for(loopVariabele = subStringIdx; loopVariabele<textLength; loopVariabele++)
{
textToChange[loopVariabele] = textToChange[loopVariabele + strlen(removeThis)];
}
}
}
Leveraging 'strstr', and 'memmove' standard "C" library functions
// Remove all occurences of 'source' from 'message'.
void removeAll(char *message, char *source)
{
int len = strlen(source) ;
for (char *x = message ; x=strstr(x, source) ; ) {
// Copy everything after 'source', including terminating nul.
memmove(x, x+len, strlen(x+len)+1) ;
} ;
}
Notes:
that solution that not properly address the trailing space(s) after a word. This can be addressed by chaning the 'memmove'.
Probably make sense to make the function return the number of substitutions, or some other meaningful result

Python's binascii.unhexlify function in C

I'm building a program that takes input as if it is a bare MAC address and turn it into a binary string. I'm doing this on a embedded system so there is no STD. I have been trying something similar to this question but after 2 days I haven't achieved anything, I'm really bad with these kind of things.
What I wanted is output to be equal to goal, take this into consideration:
#include <stdio.h>
int main() {
const char* goal = "\xaa\xbb\xcc\xdd\xee\xff";
printf("Goal: %s\n", goal);
char* input = "aabbccddeeff";
printf("Input: %s\n", input);
char* output = NULL;
// Magic code here
if (output == goal) {
printf("Did work! Yay!");
} else {
printf("Did not work, keep trying");
}
}
Thanks, this is for a personal project and I really want to finish it
First, your comparison should use strcmp else it'll be always wrong.
Then, I would read the string 2-char by 2-char and convert each "digit" to its value (0-15), then compose the result with shifting
#include <stdio.h>
#include <string.h>
// helper function to convert a char 0-9 or a-f to its decimal value (0-16)
// if something else is passed returns 0...
int a2v(char c)
{
if ((c>='0')&&(c<='9'))
{
return c-'0';
}
if ((c>='a')&&(c<='f'))
{
return c-'a'+10;
}
else return 0;
}
int main() {
const char* goal = "\xaa\xbb\xcc\xdd\xee\xff";
printf("Goal: %s\n", goal);
const char* input = "aabbccddeeff";
int i;
char output[strlen(input)/2 + 1];
char *ptr = output;
for (i=0;i<strlen(input);i+=2)
{
*ptr++ = (a2v(input[i])<<4) + a2v(input[i]);
}
*ptr = '\0';
printf("Goal: %s\n", output);
if (strcmp(output,goal)==0) {
printf("Did work! Yay!");
} else {
printf("Did not work, keep trying");
}
}

Very Basic Encryption

#include <stdio.h>
int limit;
char alp[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
void encode(char message[21],char enc_message[21],int key);
void decode(char enc_message[21],char dec_message[21],int key);
main()
{
int key,i=0,j=0;
char message[21];
char enc_message[21];
char dec_message[21];
char encrypted[21];
char a='\0';
printf("Input the characters to encrypt\n");
while(i<21 && a!='\n')
{
scanf("%c",&a);
message[i]=a;
i=i+1;
}
for(i=0;;i++) /*custom strlen*/
{
if( message[i]= '\0')
{
limit=i;
break;
}
}
printf("Input the key");
scanf("%d",key);
for(i=0;i<21;i++)
{
enc_message[i]=message[i];
}
encode(message[21],enc_message[21],key);
for(i=0;i<21;i++)
{
dec_message[i]=enc_message[i];
}
for(i=0;i<limit;i++)
{
printf("%c",enc_message[i]);
}
printf("\n\n");
decode(enc_message[21],dec_message[21],key);
for(i=0;i<limit;i++)
{
printf("%c",dec_message[i]);
}
}
void encode(char message[21],char enc_message[21],int key)
{
/*char temp[21];*/
int x,y;
for(x=0;x<limit;x++) /* message check */
{
for(y=0;y<26;y++) /* <----- alphabet check */
{
if (enc_message[x]==alp[y]) enc_message[x]=alp[y+key];
}
}
}
/*------------------------------------------------------------------------*/
void decode(char enc_message[21],char dec_message[21],int key)
{
int x,y;
for (x=0;x<limit;x++)
{
for(y=0;y<26;y++)
{
if (dec_message[x]==alp[y+key]) dec_message[x]=alp[y];
}
}
}
The compiler says,the mistake has to do with the way I call functions(and write them)and says: passing argument1 of 'encode' makes pointer from integer without a cast ,and that is for argument 2 of 'encode' and the exact same for 'decode'
Thanks in advance!
You are passing a single element and it's not even a valid element, try
decode(enc_message, dec_message, key);
Also, format your code so it's readable that is really important, and looping to compute the length of the string to use it in another loop is not a very smart thing, print it in a loop like
for (int i = 0 ; enc_message[i] != '\0' ; ++i) ...
also, don't over use break, just think about the logical condition for the loop, it's the same one where you break. Code is much more readable if the condition appears in the right place.

How to omit quotation marks usage in char type?

I'm having a really hard time adjusting function to my needs. First of all look at those three files and notice how I have to call f_texture function in main function in order to make it work:
externs.h
#ifndef EXTERNS_H_
#define EXTERNS_H_
extern char t_about[100];
extern int friction;
extern int f_texture(char* ,char*);
#endif
functionA.c
#include <stdio.h>
#include "externs.h"
int main()
{
f_texture("rough","friction");
printf("Friction: %d\n", friction);
f_texture("rough","t_about");
return 0;
}
functionB.c
#include "externs.h"
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
char t_about[100];
int friction;
int f_texture(char* texture,char* what_is_needed)
{
/*Checking if both values are present*/
assert(what_is_needed);
assert(texture);
/*Static array in order to prevent it's disappearance*/
memset(t_about, '\0', sizeof(t_about));
/*Configuring variables for desired texture*/
if (strcmp(texture, "smooth") == 0)
{
strcpy(t_about, "The surface is perfectly smooth, without any "
"protuberances.\n");
friction = 0;
}
else if (strcmp(texture, "rough") == 0)
{
strcpy(t_about, "Rough bumps can be feeled under my fingertips.\n");
friction = 4;
}
/*In case of absent keyword of desired texture it will crash the program*/
else
{
assert(!what_is_needed);
}
/*Returning desired value*/
if (strcmp(what_is_needed, "t_about") == 0)
{
int i=0;
while (t_about[i] != '\0')
{
printf("%c", t_about[i]);
i++;
}
}
else if (strcmp(what_is_needed, "friction") == 0)
{
return friction;
}
/*In case of absent keyword of desired value it will crash the program*/
else
{
assert(!what_is_needed);
}
return 0;
}
And now here is my question: How to rewrite this code to make it possible to call f_texture function without using quotation marks inside? I mean instead of f_texture("abcd","efgh") just to type f_texture(abcd,efgh). I've noticed that this way it's required just after I've wrote this code.
Thanks in advance.
If you don't want to assign string constants to variables or preprocessor object macros, another option is to use preprocessor function macros, using the stringification feature:
#define call_f_texture(a,b) f_texture(#a,#b)
....
call_f_texture(rough,friction);
The C preprocessor will turn this into
f_texture("rough","friction");
You can also use some macros:
#define ROUGH "rough"
#define FRICTION "friction"
#define T_ABOUT "t_about"
int main()
{
f_texture(ROUGH, FRICTION);
printf("Friction: %d\n", friction);
f_texture(ROUGH, T_ABOUT);
return 0;
}
You can do like this,
char rough[]="rough";
char friction[]= "friction";
and call
f_texture(rough, friction);
char a[MAX] = "rouch";
char b[MAX} = "friction";
int main()
{
f_texture();
...
}
int f_texture()
{
/*Checking if both values are present*/
assert(b);
assert(a);
}
or
int f_texture(char* a,char* b)
{
/*Checking if both values are present*/
assert(b);
assert(a);
...
}
int main()
{
char a[MAX] = "rouch";
char b[MAX} = "friction";
f_texture(a,b);
...
}

Resources