Printing % to a string? I need MANY % to get the percent symbol

Started by
23 comments, last by diligentcircle 5 years, 12 months ago

You should never use sprintf to begin with, because it has no way of checking if you are writing past the end of the buffer. A valid alternative is snprintf. Then again, you should only use this when you need formatting. When passing the string around, when storing it or when sending it to the drawing function, you should just handle it as a plain string, without doing any formatting.

EDIT: Oh, and please use std::string if you are programming in C++. You are much less likely to mess up that way.

Advertisement

You're using sprintf wrongly, and that causes reformatting. Change that to this:

https://pastebin.com/sj2ugGEt

Or, even better, since you just need to copy the string, use strcpy instead of sprintf:

https://pastebin.com/BiYk356C

(Using Pastebin because the forum keeps erasing half my post when I try to use two code tags.)

Repeat for all affected functions.

Im aware of the folly of using char arrays :)

The problem is my projects are already very large and there is alot of work with rewriting all the functions that use char arrays to instead use std::string (which I get the impression would be the best replacement).

3 hours ago, suliman said:

Im aware of the folly of using char arrays :)

The problem is my projects are already very large and there is alot of work with rewriting all the functions that use char arrays to instead use std::string (which I get the impression would be the best replacement).

This is something very frequent. In companies or organizations, professional softwares or free softwares. Once there is a new way to do a common thing, for sure the old way has to change everywhere. This is why functions exist: limitting code duplication.

But the best thing you can do, is to start to change.

Also, this does not explain why you are focusing on sprintf. Stringstreams also work with char arrays (just ensure your array will be big enough thought, thus exposing some potential buffer overflow issues...).

C strings are perfectly fine if you use them correctly. That entails not reformatting the same string multiple times, and using the strcpy function to copy strings, not sprintf.

I disagree with the implicit suggestion that you should use C++ strings for new code while keeping C strings for old code. The most important aspect when it comes to readability is consistency, so if you're using C strings everywhere, starting to use C++ strings some places while keeping it as C strings in other places will make your code harder to read, and that's a problem. That's why my suggestions haven't been "ditch C strings" like everyone else, but rather "use C strings correctly".

The only other suggestion I would make is that if you prefer the C style (as I do; I think C++ is an ugly language), you should use C, not C++. That also means you use e.g. malloc and free instead of new and delete, a good naming convention instead of namespaces, and regular structs instead of classes. But you don't have to migrate already existing projects (C style programming support for C++ isn't going away), and if you choose to do so, you don't have to do it overnight.

29 minutes ago, JulieMaru-chan said:

I disagree with the implicit suggestion that you should use C++ strings for new code while keeping C strings for old code. The most important aspect when it comes to readability is consistency, so if you're using C strings everywhere, starting to use C++ strings some places while keeping it as C strings in other places will make your code harder to read, and that's a problem.

When you have programs over millions line of code, there is no other choices than the one I suggested. Keeping something deprecated or dangerous will lead to the program to become deprecated, hard to maintain and which will have more bugs. And changing it to something not deprecated and/or more safe, if that's about 2 or 3 calls that's OK. But if it's about to check hundred thousands of files, in several hundreds (or thousands) of locations, no one will accept to do it. That's not about agreement or not.That's just about faisability and risks.

Doing it progressively allows to keep new code up to date and revised code also up to date and tested over regressions, security issues, bugs and any concerns one should look at when changing some part of existing code. It also allows to start to do a change. Keeping unsafe functions is, to my own opinion, more bad than to break consistency for the moment you'll do the changes...

Since when are C strings deprecated?

In c++?  Since std::string, I'd say, except as string literals.

 

After many years of using C++, the main reason I wouldn't go back to C is std::string. Next in the list of things I would miss are destructors that make sure things are cleaned up at the right time (a.k.a., RAII, or "resource acquisition is initialization", which is a name I never quite understood). Then come containers, like std::vector. The rest of the language I could probably do without.

 

"Deprecated" has a specific meaning: features that are slated for removal in a future version. It does not mean "not recommended". Legacy C code is not deprecated in C++, and that goes for strcpy and sprintf as well. You'll be able to use them for the foreseeable future. (The strings themselves obviously can't be deprecated, since they're literally just char pointers.)

C strings are not inherently buggy, by the way, let alone "unsafe". They just need to be used correctly. If you're going to argue that any language feature that can be used incorrectly in dangerous ways is a problem, then C++ certainly isn't a language you would turn to.

This topic is closed to new replies.

Advertisement