How can I make sure that there is no limit to how long a password can be?
I wrote a code in C where the user has to have a "$", a number and a capital number in their password for it to be valid, but I'm confused as to what to do so that the password can be as long as they want, without me having to write char password[100000000000]
or something like that.
int something = 100;
char password[something];
int index = 0;
int x = 0;
int y = 0;
int z = 0;
printf("Enter Password: "); //Mike$4
scanf("%s", password);
do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked
if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}
if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){
if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
This is my code. Thanks!
c
|
show 5 more comments
I wrote a code in C where the user has to have a "$", a number and a capital number in their password for it to be valid, but I'm confused as to what to do so that the password can be as long as they want, without me having to write char password[100000000000]
or something like that.
int something = 100;
char password[something];
int index = 0;
int x = 0;
int y = 0;
int z = 0;
printf("Enter Password: "); //Mike$4
scanf("%s", password);
do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked
if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}
if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){
if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
This is my code. Thanks!
c
1
Build a computer with unlimited memory. Or move to dynamic allocation of the string. Note, on some UNIX systems you can usem
"directive" with scanf%s
modifier like%ms
.
– Kamil Cuk
Jan 3 at 0:26
1
@KenWhite but you can allocate it chunk-by-chunk (even character-by-character) and don't waste a single byte
– Ctx
Jan 3 at 0:34
4
"no limit to how long a password can be" is a mis-guided goal. An unlimited length password is a hacker's delight as it allows external control to overwhelm memory resources. Set a generous upper bound instead like 256. Or do you like Star Trek (Data's Password)?
– chux
Jan 3 at 0:39
1
@KenWhite: The requirements of the problem are not to validate that an entered string is the password to some account. The requirements of the problem are to test whether a string entered as a proposed password satisfies policy requirements that the password contains at least one dollar sign, one number sign, and one uppercase letter. It is a student exercise in processing characters and writing simple loops and tests. It does not call for dynamic memory allocation.
– Eric Postpischil
Jan 3 at 2:36
1
Ming - I've noticed you have asked 8 questions in the past few weeks and yet to accept any. Suggest reviewing What should I do when someone answers my question?.
– chux
Jan 3 at 3:49
|
show 5 more comments
I wrote a code in C where the user has to have a "$", a number and a capital number in their password for it to be valid, but I'm confused as to what to do so that the password can be as long as they want, without me having to write char password[100000000000]
or something like that.
int something = 100;
char password[something];
int index = 0;
int x = 0;
int y = 0;
int z = 0;
printf("Enter Password: "); //Mike$4
scanf("%s", password);
do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked
if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}
if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){
if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
This is my code. Thanks!
c
I wrote a code in C where the user has to have a "$", a number and a capital number in their password for it to be valid, but I'm confused as to what to do so that the password can be as long as they want, without me having to write char password[100000000000]
or something like that.
int something = 100;
char password[something];
int index = 0;
int x = 0;
int y = 0;
int z = 0;
printf("Enter Password: "); //Mike$4
scanf("%s", password);
do{ // If index is strlen, then we checked every char of pw
// Ex. Password is length 6, then index 0 - 5 will be checked
if(index == strlen(password) && x>0 && y>0 && z>0){
printf("Good password!");
break;
}
if(index == strlen(password) && (x==0 || y==0 || z==0)){
printf("BAD PASSWORD");
break;
}
if(isupper(password[index]) || isdigit(password[index]) ||
password[index] == '$'){
if(isupper(password[index])){
x++; index++;
continue;}
if(isdigit(password[index])){
y++; index++;
continue;}
if(password[index] == '$'){
z++; index++;
continue;}
}else{index++;
continue;
}
}while(index <= strlen(password));
This is my code. Thanks!
c
c
asked Jan 3 at 0:24
mingming
1413
1413
1
Build a computer with unlimited memory. Or move to dynamic allocation of the string. Note, on some UNIX systems you can usem
"directive" with scanf%s
modifier like%ms
.
– Kamil Cuk
Jan 3 at 0:26
1
@KenWhite but you can allocate it chunk-by-chunk (even character-by-character) and don't waste a single byte
– Ctx
Jan 3 at 0:34
4
"no limit to how long a password can be" is a mis-guided goal. An unlimited length password is a hacker's delight as it allows external control to overwhelm memory resources. Set a generous upper bound instead like 256. Or do you like Star Trek (Data's Password)?
– chux
Jan 3 at 0:39
1
@KenWhite: The requirements of the problem are not to validate that an entered string is the password to some account. The requirements of the problem are to test whether a string entered as a proposed password satisfies policy requirements that the password contains at least one dollar sign, one number sign, and one uppercase letter. It is a student exercise in processing characters and writing simple loops and tests. It does not call for dynamic memory allocation.
– Eric Postpischil
Jan 3 at 2:36
1
Ming - I've noticed you have asked 8 questions in the past few weeks and yet to accept any. Suggest reviewing What should I do when someone answers my question?.
– chux
Jan 3 at 3:49
|
show 5 more comments
1
Build a computer with unlimited memory. Or move to dynamic allocation of the string. Note, on some UNIX systems you can usem
"directive" with scanf%s
modifier like%ms
.
– Kamil Cuk
Jan 3 at 0:26
1
@KenWhite but you can allocate it chunk-by-chunk (even character-by-character) and don't waste a single byte
– Ctx
Jan 3 at 0:34
4
"no limit to how long a password can be" is a mis-guided goal. An unlimited length password is a hacker's delight as it allows external control to overwhelm memory resources. Set a generous upper bound instead like 256. Or do you like Star Trek (Data's Password)?
– chux
Jan 3 at 0:39
1
@KenWhite: The requirements of the problem are not to validate that an entered string is the password to some account. The requirements of the problem are to test whether a string entered as a proposed password satisfies policy requirements that the password contains at least one dollar sign, one number sign, and one uppercase letter. It is a student exercise in processing characters and writing simple loops and tests. It does not call for dynamic memory allocation.
– Eric Postpischil
Jan 3 at 2:36
1
Ming - I've noticed you have asked 8 questions in the past few weeks and yet to accept any. Suggest reviewing What should I do when someone answers my question?.
– chux
Jan 3 at 3:49
1
1
Build a computer with unlimited memory. Or move to dynamic allocation of the string. Note, on some UNIX systems you can use
m
"directive" with scanf %s
modifier like %ms
.– Kamil Cuk
Jan 3 at 0:26
Build a computer with unlimited memory. Or move to dynamic allocation of the string. Note, on some UNIX systems you can use
m
"directive" with scanf %s
modifier like %ms
.– Kamil Cuk
Jan 3 at 0:26
1
1
@KenWhite but you can allocate it chunk-by-chunk (even character-by-character) and don't waste a single byte
– Ctx
Jan 3 at 0:34
@KenWhite but you can allocate it chunk-by-chunk (even character-by-character) and don't waste a single byte
– Ctx
Jan 3 at 0:34
4
4
"no limit to how long a password can be" is a mis-guided goal. An unlimited length password is a hacker's delight as it allows external control to overwhelm memory resources. Set a generous upper bound instead like 256. Or do you like Star Trek (Data's Password)?
– chux
Jan 3 at 0:39
"no limit to how long a password can be" is a mis-guided goal. An unlimited length password is a hacker's delight as it allows external control to overwhelm memory resources. Set a generous upper bound instead like 256. Or do you like Star Trek (Data's Password)?
– chux
Jan 3 at 0:39
1
1
@KenWhite: The requirements of the problem are not to validate that an entered string is the password to some account. The requirements of the problem are to test whether a string entered as a proposed password satisfies policy requirements that the password contains at least one dollar sign, one number sign, and one uppercase letter. It is a student exercise in processing characters and writing simple loops and tests. It does not call for dynamic memory allocation.
– Eric Postpischil
Jan 3 at 2:36
@KenWhite: The requirements of the problem are not to validate that an entered string is the password to some account. The requirements of the problem are to test whether a string entered as a proposed password satisfies policy requirements that the password contains at least one dollar sign, one number sign, and one uppercase letter. It is a student exercise in processing characters and writing simple loops and tests. It does not call for dynamic memory allocation.
– Eric Postpischil
Jan 3 at 2:36
1
1
Ming - I've noticed you have asked 8 questions in the past few weeks and yet to accept any. Suggest reviewing What should I do when someone answers my question?.
– chux
Jan 3 at 3:49
Ming - I've noticed you have asked 8 questions in the past few weeks and yet to accept any. Suggest reviewing What should I do when someone answers my question?.
– chux
Jan 3 at 3:49
|
show 5 more comments
3 Answers
3
active
oldest
votes
If you truly want unlimited length (although its utility is somewhat questionable -- it's probably better to just pick a big limit and be done with it), you're going to have to ditch scanf
for something like fgets
that allows you to specify how many characters to read, then read the input in chunks. You'll probably want to use an easy-to-grow structure (like a linked list of slightly-less-than-page-sized string buffers) to read in these chunks, then allocate a buffer for the final string once you hit a newline (or EOF, depending on your desired semantics) in your input.
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
add a comment |
The simplest way would be to use fgets
. Note that scanf("%s")
will only get a single word and some passwords might have spaces. But, the real reason to use fgets
is that you can prevent overflow as in:
char password[1000];
fgets(password,sizeof(password),stdin);
char *cp = strchr(password,'n');
if (cp != NULL)
*cp = 0;
That's the simplest solution.
But, if you really need a large password [of unspecified length], you can grow the password
variable from realloc
, just as would be done for a dynamic array:
char *password = NULL;
int pwmax = 0;
int pwlen = 0;
void *
xrealloc(void *ptr,size_t len)
{
void *tmp;
tmp = realloc(ptr,len);
if (tmp == NULL) {
free(ptr);
exit(1);
}
return ptr;
}
while (1) {
int chr = fgetc(stdin);
if (chr == EOF)
break;
if (chr == 'n')
break;
if (pwlen >= pwmax) {
if (pwlen >= 1000000) {
fprintf(stderr,"password beyond reasonable max limitn")
exit(1);
}
pwmax += 100;
password = xrealloc(password,pwmax);
}
password[pwlen++] = chr;
}
password = xrealloc(password,pwlen + 1);
password[pwlen] = 0;
2
Or, if available, just use POSIXgetline
for the same effect, but see @chux comment to the original question.password = realloc(password, ...
bad,void *tmp = realloc (password, ...
and thenif (tmp) password = tmp;
better...
– David C. Rankin
Jan 3 at 0:49
@DavidC.Rankin I'm aware ofrealloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the fullrealloc
code recovery here, but just to keep the peace ...
– Craig Estey
Jan 3 at 0:59
But you can. Ifrealloc
returnsNULL
, your original block of memory is still valid and can be referenced and freed viapassword
. If you letrealloc
setpassword = NULL;
on failure, you create a memory leak by losing the address held bypassword
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to arealloc
fail.
– David C. Rankin
Jan 3 at 1:06
1
@DavidC.Rankin It's not about therealloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usuallymalloc
failure is terminal condition from a practical standpoint.
– Craig Estey
Jan 3 at 1:17
Ok, I see we are talking about two different sides of the same coin - yes, if you can'trealloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without anexit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.
– David C. Rankin
Jan 3 at 1:23
add a comment |
Simply process one character of the password at a time; there is no need to have it all in memory at once.
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
printf("Enter password: ");
bool SawDollar = false;
bool SawDigit = false;
bool SawUpper = false;
while (1)
{
int c = getchar();
if (c == EOF || isspace(c))
break;
if (c == '$')
SawDollar = true;
else if (isdigit(c))
SawDigit = true;
else if (isupper(c))
SawUpper = true;
}
if (SawDollar && SawDigit && SawUpper)
printf("Good password!n");
else
printf("Bad password.n");
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54014894%2fhow-can-i-make-sure-that-there-is-no-limit-to-how-long-a-password-can-be%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
If you truly want unlimited length (although its utility is somewhat questionable -- it's probably better to just pick a big limit and be done with it), you're going to have to ditch scanf
for something like fgets
that allows you to specify how many characters to read, then read the input in chunks. You'll probably want to use an easy-to-grow structure (like a linked list of slightly-less-than-page-sized string buffers) to read in these chunks, then allocate a buffer for the final string once you hit a newline (or EOF, depending on your desired semantics) in your input.
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
add a comment |
If you truly want unlimited length (although its utility is somewhat questionable -- it's probably better to just pick a big limit and be done with it), you're going to have to ditch scanf
for something like fgets
that allows you to specify how many characters to read, then read the input in chunks. You'll probably want to use an easy-to-grow structure (like a linked list of slightly-less-than-page-sized string buffers) to read in these chunks, then allocate a buffer for the final string once you hit a newline (or EOF, depending on your desired semantics) in your input.
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
add a comment |
If you truly want unlimited length (although its utility is somewhat questionable -- it's probably better to just pick a big limit and be done with it), you're going to have to ditch scanf
for something like fgets
that allows you to specify how many characters to read, then read the input in chunks. You'll probably want to use an easy-to-grow structure (like a linked list of slightly-less-than-page-sized string buffers) to read in these chunks, then allocate a buffer for the final string once you hit a newline (or EOF, depending on your desired semantics) in your input.
If you truly want unlimited length (although its utility is somewhat questionable -- it's probably better to just pick a big limit and be done with it), you're going to have to ditch scanf
for something like fgets
that allows you to specify how many characters to read, then read the input in chunks. You'll probably want to use an easy-to-grow structure (like a linked list of slightly-less-than-page-sized string buffers) to read in these chunks, then allocate a buffer for the final string once you hit a newline (or EOF, depending on your desired semantics) in your input.
answered Jan 3 at 0:38


Craig MeierCraig Meier
1,245612
1,245612
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
add a comment |
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
Yeah for passwords I guess it isn't terribly useful, but I was just wondering if there was a way for me to set an undefined length I guess, rather than "unlimited length".
– ming
Jan 3 at 22:46
add a comment |
The simplest way would be to use fgets
. Note that scanf("%s")
will only get a single word and some passwords might have spaces. But, the real reason to use fgets
is that you can prevent overflow as in:
char password[1000];
fgets(password,sizeof(password),stdin);
char *cp = strchr(password,'n');
if (cp != NULL)
*cp = 0;
That's the simplest solution.
But, if you really need a large password [of unspecified length], you can grow the password
variable from realloc
, just as would be done for a dynamic array:
char *password = NULL;
int pwmax = 0;
int pwlen = 0;
void *
xrealloc(void *ptr,size_t len)
{
void *tmp;
tmp = realloc(ptr,len);
if (tmp == NULL) {
free(ptr);
exit(1);
}
return ptr;
}
while (1) {
int chr = fgetc(stdin);
if (chr == EOF)
break;
if (chr == 'n')
break;
if (pwlen >= pwmax) {
if (pwlen >= 1000000) {
fprintf(stderr,"password beyond reasonable max limitn")
exit(1);
}
pwmax += 100;
password = xrealloc(password,pwmax);
}
password[pwlen++] = chr;
}
password = xrealloc(password,pwlen + 1);
password[pwlen] = 0;
2
Or, if available, just use POSIXgetline
for the same effect, but see @chux comment to the original question.password = realloc(password, ...
bad,void *tmp = realloc (password, ...
and thenif (tmp) password = tmp;
better...
– David C. Rankin
Jan 3 at 0:49
@DavidC.Rankin I'm aware ofrealloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the fullrealloc
code recovery here, but just to keep the peace ...
– Craig Estey
Jan 3 at 0:59
But you can. Ifrealloc
returnsNULL
, your original block of memory is still valid and can be referenced and freed viapassword
. If you letrealloc
setpassword = NULL;
on failure, you create a memory leak by losing the address held bypassword
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to arealloc
fail.
– David C. Rankin
Jan 3 at 1:06
1
@DavidC.Rankin It's not about therealloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usuallymalloc
failure is terminal condition from a practical standpoint.
– Craig Estey
Jan 3 at 1:17
Ok, I see we are talking about two different sides of the same coin - yes, if you can'trealloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without anexit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.
– David C. Rankin
Jan 3 at 1:23
add a comment |
The simplest way would be to use fgets
. Note that scanf("%s")
will only get a single word and some passwords might have spaces. But, the real reason to use fgets
is that you can prevent overflow as in:
char password[1000];
fgets(password,sizeof(password),stdin);
char *cp = strchr(password,'n');
if (cp != NULL)
*cp = 0;
That's the simplest solution.
But, if you really need a large password [of unspecified length], you can grow the password
variable from realloc
, just as would be done for a dynamic array:
char *password = NULL;
int pwmax = 0;
int pwlen = 0;
void *
xrealloc(void *ptr,size_t len)
{
void *tmp;
tmp = realloc(ptr,len);
if (tmp == NULL) {
free(ptr);
exit(1);
}
return ptr;
}
while (1) {
int chr = fgetc(stdin);
if (chr == EOF)
break;
if (chr == 'n')
break;
if (pwlen >= pwmax) {
if (pwlen >= 1000000) {
fprintf(stderr,"password beyond reasonable max limitn")
exit(1);
}
pwmax += 100;
password = xrealloc(password,pwmax);
}
password[pwlen++] = chr;
}
password = xrealloc(password,pwlen + 1);
password[pwlen] = 0;
2
Or, if available, just use POSIXgetline
for the same effect, but see @chux comment to the original question.password = realloc(password, ...
bad,void *tmp = realloc (password, ...
and thenif (tmp) password = tmp;
better...
– David C. Rankin
Jan 3 at 0:49
@DavidC.Rankin I'm aware ofrealloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the fullrealloc
code recovery here, but just to keep the peace ...
– Craig Estey
Jan 3 at 0:59
But you can. Ifrealloc
returnsNULL
, your original block of memory is still valid and can be referenced and freed viapassword
. If you letrealloc
setpassword = NULL;
on failure, you create a memory leak by losing the address held bypassword
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to arealloc
fail.
– David C. Rankin
Jan 3 at 1:06
1
@DavidC.Rankin It's not about therealloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usuallymalloc
failure is terminal condition from a practical standpoint.
– Craig Estey
Jan 3 at 1:17
Ok, I see we are talking about two different sides of the same coin - yes, if you can'trealloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without anexit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.
– David C. Rankin
Jan 3 at 1:23
add a comment |
The simplest way would be to use fgets
. Note that scanf("%s")
will only get a single word and some passwords might have spaces. But, the real reason to use fgets
is that you can prevent overflow as in:
char password[1000];
fgets(password,sizeof(password),stdin);
char *cp = strchr(password,'n');
if (cp != NULL)
*cp = 0;
That's the simplest solution.
But, if you really need a large password [of unspecified length], you can grow the password
variable from realloc
, just as would be done for a dynamic array:
char *password = NULL;
int pwmax = 0;
int pwlen = 0;
void *
xrealloc(void *ptr,size_t len)
{
void *tmp;
tmp = realloc(ptr,len);
if (tmp == NULL) {
free(ptr);
exit(1);
}
return ptr;
}
while (1) {
int chr = fgetc(stdin);
if (chr == EOF)
break;
if (chr == 'n')
break;
if (pwlen >= pwmax) {
if (pwlen >= 1000000) {
fprintf(stderr,"password beyond reasonable max limitn")
exit(1);
}
pwmax += 100;
password = xrealloc(password,pwmax);
}
password[pwlen++] = chr;
}
password = xrealloc(password,pwlen + 1);
password[pwlen] = 0;
The simplest way would be to use fgets
. Note that scanf("%s")
will only get a single word and some passwords might have spaces. But, the real reason to use fgets
is that you can prevent overflow as in:
char password[1000];
fgets(password,sizeof(password),stdin);
char *cp = strchr(password,'n');
if (cp != NULL)
*cp = 0;
That's the simplest solution.
But, if you really need a large password [of unspecified length], you can grow the password
variable from realloc
, just as would be done for a dynamic array:
char *password = NULL;
int pwmax = 0;
int pwlen = 0;
void *
xrealloc(void *ptr,size_t len)
{
void *tmp;
tmp = realloc(ptr,len);
if (tmp == NULL) {
free(ptr);
exit(1);
}
return ptr;
}
while (1) {
int chr = fgetc(stdin);
if (chr == EOF)
break;
if (chr == 'n')
break;
if (pwlen >= pwmax) {
if (pwlen >= 1000000) {
fprintf(stderr,"password beyond reasonable max limitn")
exit(1);
}
pwmax += 100;
password = xrealloc(password,pwmax);
}
password[pwlen++] = chr;
}
password = xrealloc(password,pwlen + 1);
password[pwlen] = 0;
edited Jan 3 at 1:03
answered Jan 3 at 0:38
Craig EsteyCraig Estey
15.3k21131
15.3k21131
2
Or, if available, just use POSIXgetline
for the same effect, but see @chux comment to the original question.password = realloc(password, ...
bad,void *tmp = realloc (password, ...
and thenif (tmp) password = tmp;
better...
– David C. Rankin
Jan 3 at 0:49
@DavidC.Rankin I'm aware ofrealloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the fullrealloc
code recovery here, but just to keep the peace ...
– Craig Estey
Jan 3 at 0:59
But you can. Ifrealloc
returnsNULL
, your original block of memory is still valid and can be referenced and freed viapassword
. If you letrealloc
setpassword = NULL;
on failure, you create a memory leak by losing the address held bypassword
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to arealloc
fail.
– David C. Rankin
Jan 3 at 1:06
1
@DavidC.Rankin It's not about therealloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usuallymalloc
failure is terminal condition from a practical standpoint.
– Craig Estey
Jan 3 at 1:17
Ok, I see we are talking about two different sides of the same coin - yes, if you can'trealloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without anexit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.
– David C. Rankin
Jan 3 at 1:23
add a comment |
2
Or, if available, just use POSIXgetline
for the same effect, but see @chux comment to the original question.password = realloc(password, ...
bad,void *tmp = realloc (password, ...
and thenif (tmp) password = tmp;
better...
– David C. Rankin
Jan 3 at 0:49
@DavidC.Rankin I'm aware ofrealloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the fullrealloc
code recovery here, but just to keep the peace ...
– Craig Estey
Jan 3 at 0:59
But you can. Ifrealloc
returnsNULL
, your original block of memory is still valid and can be referenced and freed viapassword
. If you letrealloc
setpassword = NULL;
on failure, you create a memory leak by losing the address held bypassword
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to arealloc
fail.
– David C. Rankin
Jan 3 at 1:06
1
@DavidC.Rankin It's not about therealloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usuallymalloc
failure is terminal condition from a practical standpoint.
– Craig Estey
Jan 3 at 1:17
Ok, I see we are talking about two different sides of the same coin - yes, if you can'trealloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without anexit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.
– David C. Rankin
Jan 3 at 1:23
2
2
Or, if available, just use POSIX
getline
for the same effect, but see @chux comment to the original question. password = realloc(password, ...
bad, void *tmp = realloc (password, ...
and then if (tmp) password = tmp;
better...– David C. Rankin
Jan 3 at 0:49
Or, if available, just use POSIX
getline
for the same effect, but see @chux comment to the original question. password = realloc(password, ...
bad, void *tmp = realloc (password, ...
and then if (tmp) password = tmp;
better...– David C. Rankin
Jan 3 at 0:49
@DavidC.Rankin I'm aware of
realloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the full realloc
code recovery here, but just to keep the peace ...– Craig Estey
Jan 3 at 0:59
@DavidC.Rankin I'm aware of
realloc
's "fail" behavior, but I'm not in the "you can meaningfully recover from it" camp. So, best to just abort. I tire of doing the full realloc
code recovery here, but just to keep the peace ...– Craig Estey
Jan 3 at 0:59
But you can. If
realloc
returns NULL
, your original block of memory is still valid and can be referenced and freed via password
. If you let realloc
set password = NULL;
on failure, you create a memory leak by losing the address held by password
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to a realloc
fail.– David C. Rankin
Jan 3 at 1:06
But you can. If
realloc
returns NULL
, your original block of memory is still valid and can be referenced and freed via password
. If you let realloc
set password = NULL;
on failure, you create a memory leak by losing the address held by password
. That's what you are protecting against by reallocating with a temporary variable and how you recover. Granted in trivial programs, it is unlikely to happen, but that doesn't save you when the code gets moved into an app that can (and does) exhaust memory leading to a realloc
fail.– David C. Rankin
Jan 3 at 1:06
1
1
@DavidC.Rankin It's not about the
realloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usually malloc
failure is terminal condition from a practical standpoint.– Craig Estey
Jan 3 at 1:17
@DavidC.Rankin It's not about the
realloc
behavior (re. its return). It's about if you can't allocate what you need, how can the program meaningfully proceed? It needs to store something and can't get the memory to do so. So, what does it do (other than abort)? Some [carefully crafted] programs can call a function that tries to free some objects to make some room (e.g. they're just a database cache and they can be flushed), but usually malloc
failure is terminal condition from a practical standpoint.– Craig Estey
Jan 3 at 1:17
Ok, I see we are talking about two different sides of the same coin - yes, if you can't
realloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without an exit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.– David C. Rankin
Jan 3 at 1:23
Ok, I see we are talking about two different sides of the same coin - yes, if you can't
realloc
you can't proceed, but I was talking about handling a failure (and whatever cleanup is needed) gracefully without an exit(1);
. So yes, I see what you are saying, I was just looking at the other side where the failed password entry for a new user wouldn't justify a complete exit from the program.– David C. Rankin
Jan 3 at 1:23
add a comment |
Simply process one character of the password at a time; there is no need to have it all in memory at once.
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
printf("Enter password: ");
bool SawDollar = false;
bool SawDigit = false;
bool SawUpper = false;
while (1)
{
int c = getchar();
if (c == EOF || isspace(c))
break;
if (c == '$')
SawDollar = true;
else if (isdigit(c))
SawDigit = true;
else if (isupper(c))
SawUpper = true;
}
if (SawDollar && SawDigit && SawUpper)
printf("Good password!n");
else
printf("Bad password.n");
}
add a comment |
Simply process one character of the password at a time; there is no need to have it all in memory at once.
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
printf("Enter password: ");
bool SawDollar = false;
bool SawDigit = false;
bool SawUpper = false;
while (1)
{
int c = getchar();
if (c == EOF || isspace(c))
break;
if (c == '$')
SawDollar = true;
else if (isdigit(c))
SawDigit = true;
else if (isupper(c))
SawUpper = true;
}
if (SawDollar && SawDigit && SawUpper)
printf("Good password!n");
else
printf("Bad password.n");
}
add a comment |
Simply process one character of the password at a time; there is no need to have it all in memory at once.
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
printf("Enter password: ");
bool SawDollar = false;
bool SawDigit = false;
bool SawUpper = false;
while (1)
{
int c = getchar();
if (c == EOF || isspace(c))
break;
if (c == '$')
SawDollar = true;
else if (isdigit(c))
SawDigit = true;
else if (isupper(c))
SawUpper = true;
}
if (SawDollar && SawDigit && SawUpper)
printf("Good password!n");
else
printf("Bad password.n");
}
Simply process one character of the password at a time; there is no need to have it all in memory at once.
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
printf("Enter password: ");
bool SawDollar = false;
bool SawDigit = false;
bool SawUpper = false;
while (1)
{
int c = getchar();
if (c == EOF || isspace(c))
break;
if (c == '$')
SawDollar = true;
else if (isdigit(c))
SawDigit = true;
else if (isupper(c))
SawUpper = true;
}
if (SawDollar && SawDigit && SawUpper)
printf("Good password!n");
else
printf("Bad password.n");
}
answered Jan 3 at 2:18
Eric PostpischilEric Postpischil
80k889169
80k889169
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54014894%2fhow-can-i-make-sure-that-there-is-no-limit-to-how-long-a-password-can-be%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Build a computer with unlimited memory. Or move to dynamic allocation of the string. Note, on some UNIX systems you can use
m
"directive" with scanf%s
modifier like%ms
.– Kamil Cuk
Jan 3 at 0:26
1
@KenWhite but you can allocate it chunk-by-chunk (even character-by-character) and don't waste a single byte
– Ctx
Jan 3 at 0:34
4
"no limit to how long a password can be" is a mis-guided goal. An unlimited length password is a hacker's delight as it allows external control to overwhelm memory resources. Set a generous upper bound instead like 256. Or do you like Star Trek (Data's Password)?
– chux
Jan 3 at 0:39
1
@KenWhite: The requirements of the problem are not to validate that an entered string is the password to some account. The requirements of the problem are to test whether a string entered as a proposed password satisfies policy requirements that the password contains at least one dollar sign, one number sign, and one uppercase letter. It is a student exercise in processing characters and writing simple loops and tests. It does not call for dynamic memory allocation.
– Eric Postpischil
Jan 3 at 2:36
1
Ming - I've noticed you have asked 8 questions in the past few weeks and yet to accept any. Suggest reviewing What should I do when someone answers my question?.
– chux
Jan 3 at 3:49