Seekp() effects

from what I’ve heard, seekp() takes what is essentially your cursor and moves it to a new place in relation to the beginning of a stream. Could I use it to replace the character at that place or does it just output the new character behind the old one?

1
2
3
4
5
6
7
8
  #include <iostream>
  using namespace std;
  
  int main(){
    cout << "xyz";
    cout.seekp(0);
    cout << 'a';
  }

So it goes from "xyz" to "ayz".
Last edited on
You can't (in general). Once something is written to cout (standard out), you don't know what's been done with it.
On my Windows machine, your program prints "xyza".

However, if you redirect your program to a file (
main > file.txt
), you'll get "ayz" as you intended. It's finicky, and I wouldn't rely on such hackish stuff. Edit: Actually, since you're now effectively working with a file, it should follow standard file rules.


You can, however, write and manipulate output streams other than cout, e.g. a stringstream

https://en.cppreference.com/w/cpp/io/basic_ostream/seekp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <sstream>
#include <iostream>
 
int main()
{
    std::ostringstream os("hello, world");
    os.seekp(7);
    os << 'W';
    os.seekp(0, std::ios_base::end);
    os << '!';
    os.seekp(0);
    os << 'H';
    std::cout << os.str() << '\n';
}

Hello, World!


If you're talking about editing what was previously written to a console or terminal, that becomes platform-specific and we're no longer just talking about C++ streams.

For very simple console manipulation, you can use \b ("backspace") to actually move the cursor to the left
1
2
3
4
5
6
7
8
  #include <iostream>
  using namespace std;
  
  int main(){
    cout << "xyz";
    cout << "\b\b";
    cout << 'a';
  }

Will output xaz on a console (at least on Windows, I can't test *nix right now).

But if you run it through a web application or something else that might be redirecting standard out in a special way, something like that isn't guarenteed to work.
e.g. on cpp.sh, you'll get xyza .
This is also what you'll get if you redirect stdout to a file. It will literally write the 6 characters (x, y, z, backspace, backspace, a), in order, to a file.
And if you cat/type this file you created (e.g. type file.txt), you'll get xaz printed to the console, because now you're once again having the console interpret \b as "move the cursor to the left".
Last edited on
Darn. The second thing is what I was basically going for:
If you're talking about editing what was previously written to a console or terminal, that becomes platform-specific and we're no longer just talking about C++ streams.

I’d thought for sure I found a way that wasn’t os specific because all this stuff is on a online ide that I’m doing it so I have no idea how that affects things. 😞 thanks! :)
Actually, to amend my statement, when working with a file or, equivalently, redirecting output to a file, all the standard rules of writing a file apply, so the behavior of seekp should be still be cross-platform. Just wanted to clarify that.

e.g.
1
2
3
4
5
6
7
8
9
10
11
  #include <iostream>
  using namespace std;
  
  int main(){
    cout << "xyz01234567012345670123456701234567012345670123456701234567012345670123456701234567\n";
    cout << "01234567";
    cout << std::flush;
    cout << "whatever\n\nwhatever\n";
    cout.seekp(1);
    cout << 'Y'; // replaces y
  }

Will output
xYz01234567012345670123456701234567012345670123456701234567012345670123456701234567
01234567whatever

whatever

when redirected to a file. This technique can often be used when writing certain formats of files, like a WAV file, which reserves space to say how big a section of the file is, but you might not know how big the file is until you're done writing it.

But if being printed to a console, it depends on the console.

There are "TUI" (text-based user interface) libraries like ncurses that are multi-platform, and can replace text after it's printed. But I haven't used them.
Last edited on
Thought so. but the problem is I only really have the console to use because of certain qualities I depend on.. but good to know.
@highwayman,

is the console output intended for redirecting to a file, or a pipe or something like that?

If so, you would require preparing the output before it reaches cout, as in string manipulation.

Otherwise, the backspaces would end up in the output - they are processed as a kind of "command" to the cursor, it doesn't actually erase information going to the output using cout.
Exactly 😣 I’ve been trying to figure out how to manipulate stuff still in the console post-cout and best I can come up with are some control codes and those aren’t even portable so I’ve kinda just given up.
Again, a cross-platform way to do it would be ncurses. By trying to manipulate things already on the screen, you're going beyond what simple output streams are supposed to do.

https://stackoverflow.com/a/21142195/8690169
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
Last edited on
Yes, but sadly I do not have access to the ncurses library and therefore basically cannot do what I had wished I could do, I am not really ignoring any of your answers and they may be quite helpful at a later time but for now they have shown me that I will just have to wait until I can use one of your proposed solutions. Thank you for your help everyone.
Last edited on
No problem!
Topic archived. No new replies allowed.